C++ 中与 Python 属性等价的实现
在C++中有没有类似Python属性的东西?还是说用获取器和设置器(getter和setter)来做会更好呢?
3 个回答
7
标准的C++没有属性这个概念。不过,如果你是在微软的平台上开发,可以使用他们提供的语言扩展:
17
在C++中,你要么是在调用一个成员函数,要么是在访问一个数据成员。Python的属性其实就是用访问数据成员的方式来实现调用成员函数的效果,而在C++中没有一个合理的方法来做到这一点。
理论上,你可以用宏来搞定这个,比如说 #define looks_like_data really_a_function()
,但这样做既不美观,也不合理。让一个函数看起来像数据的唯一必要原因,是为了和旧的调用代码保持兼容,那些代码曾经把它当作数据来用。但是在C++中,这样做并不能保证二进制兼容性,甚至在源代码上也不兼容,因为这个宏会破坏那些已经在其他地方用 looks_like_data
作为名字的调用代码。所以这样做其实没什么意义。
你还可以做的另一件事是创建一个实际的数据成员,作为数据的“逻辑”类型的代理:
struct Proxy {
Foo *foo;
Proxy(Foo *foo) : foo(foo) { }
operator int() const {
// getter code goes here,
// use (const Foo*)foo rather than foo
}
Proxy &operator=(int a) {
// setter code goes here
}
// optionally also implement boilerplate +=, -=, etc.
};
struct Foo {
// optionally
// friend class Proxy;
Proxy looks_like_data;
Foo() : looks_like_data(this) { }
};
这几乎是合理的,但还不完全合理。使用隐式转换仍然会破坏源代码兼容性,因为有个规则是链中只能有一个用户定义的隐式转换,所以如果调用者在 looks_like_data
真的还是一个 int
的时候写了代码,并且他们的代码隐式地把那个 int
转换成了 Bar
,那么一旦 looks_like_data
变成了 Proxy
,它就不再隐式转换成 Bar
,这样一来,你还是破坏了他们的代码。
所以经过这些分析,如果你的类真的需要一些看起来像读写属性的东西,最好还是使用getter/setter函数。
13
是的,在C++中,明确的获取器(getter)和设置器(setter)是最接近这个概念的结构。