Jos*_*own 27 c++ gcc properties visual-c++ c++11
在Visual Studio中,__declspec(property)创建了与C#类似的属性.Borland C++提供的__property关键字具有完全相同的功能.在C++ 0x中,提到了一个implicit可以扩展以实现相同功能的关键字.但它没有进入规范.
我正在寻找一种可移植且相对干净的方法来声明语法上含糖的属性,这些属性将在最新的Windows,OSX和Linux编译器中编译.我不关心编译器兼容性,每个平台只有一个编译器.
我不是在寻找需要括号来获取或设置属性的属性的替代方法,例如分隔getter和setter的重载方法.
这是在Visual Studio 2010中编译的理想用法:
#define _property(_type, _name, _get, _put) __declspec(property(get=_get, put=_put)) _type _name
#define _property_readonly(_type, _name, _get) __declspec(property(get=_get)) _type _name
class Window
{
public:
_property_readonly(void*, Handle, GetHandle);
_property(bool, Visible, GetVisible, SetVisible);
void* GetHandle();
bool GetVisible();
void SetVisible(bool);
}
void main()
{
Window MainWindow;
if (!MainWindow.Visible)
MainWindow.Visible = true;
}
Run Code Online (Sandbox Code Playgroud)
650*_*502 27
这与你所要求的类似,是(我希望)标准C++ ......
#include <iostream>
template<typename C, typename T, T (C::*getter)(), void (C::*setter)(const T&)>
struct Property
{
C *instance;
Property(C *instance)
: instance(instance)
{
}
operator T () const
{
return (instance->*getter)();
}
Property& operator=(const T& value)
{
(instance->*setter)(value);
return *this;
}
template<typename C2, typename T2,
T2 (C2::*getter2)(), void (C2::*setter2)(const T2&)>
Property& operator=(const Property<C2, T2, getter2, setter2>& other)
{
return *this = (other.instance->*getter2)();
}
Property& operator=(const Property& other)
{
return *this = (other.instance->*getter)();
}
};
//////////////////////////////////////////////////////////////////////////
struct Foo
{
int x_, y_;
void setX(const int& x) { x_ = x; std::cout << "x new value is " << x << "\n"; }
int getX() { std::cout << "reading x_\n"; return x_; }
void setY(const int& y) { y_ = y; std::cout << "y new value is " << y << "\n"; }
int getY() { std::cout << "reading y_\n"; return y_; }
Property<Foo, int, &Foo::getX, &Foo::setX> x;
Property<Foo, int, &Foo::getY, &Foo::setY> y;
Foo(int x0, int y0)
: x_(x0), y_(y0), x(this), y(this)
{
}
};
int square(int x)
{
return x*x;
}
int main(int argc, const char *argv[])
{
Foo foo(10, 20);
Foo foo2(100, 200);
int x = foo.x; std::cout << x << "\n";
int y = foo.y; std::cout << y << "\n";
foo.x = 42; std::cout << "assigned!\n";
x = foo.x; std::cout << x << "\n";
std::cout << "same instance prop/prop assign!\n";
foo.x = foo.y;
std::cout << "different instances prop/prop assign\n";
foo.x = foo2.x;
std::cout << "calling a function accepting an int parameter\n";
std::cout << "square(" << foo.x << ") = " << square(foo.x) << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
您可以从main使用中看到透明,只要您分配类型T(此处int)的值或隐式转换T为属性,并且只要您将它们转换回T读取值即可.
行为将有所不同,但是如果您传递foo.x给模板函数,因为类型foo.x不是,int而是Property<Foo, int, ...>相反.
您也可能遇到非模板函数的问题...调用接受T值的函数将正常工作,但是T&参数例如会成为一个问题,因为基本上该函数要求变量直接使用该地址进行访问.出于同样的原因,您无法将属性的地址传递给接受T*参数的函数.
Clang现在已__declspec(property...)完全实施Microsoft ,并且进行了优化。因此,您可以在所有平台上的c ++中使用属性,并在基于gcc或c99的代码中混合使用。
我已经使用了一年多,并且等待它普遍出现超过五年。
它是用于抽象结构和重构代码的最强大的C ++工具之一。我一直在使用它,以便快速构建结构,然后在性能或重组需要时再进行重构。
它是无价的,我真的不明白为什么C ++标准很久以前没有采用它。但是话又说回来,它们拥有使用c ++和模板的许多复杂而肿的提升方式。
现在,Clang在每个平台上都具有很高的可移植性,以至于拥有此功能非常出色。
内发展(免费或付费版)使用Visual Studio铛几乎是无缝的,你会得到令人难以置信的调试开发工具集,只是让工作在其他的工具集和平台痛苦的对比。
我clang现在专门用于我的所有c ++开发。
| 归档时间: |
|
| 查看次数: |
6757 次 |
| 最近记录: |