我正在使用大型代码库,并且有许多公开定义的变量。不幸的是,访问这些变量的功能已经改变,这个新功能最好由公共访问器和私有实例变量封装。
所以,我试图做出这个改变。为此,我计划将每个公共属性设为私有,然后创建访问器。但是,我不想更改任何访问旧公共属性的代码。例如:
将公共属性更改为私有后,我有以下类:
class Test {
private:
int item = 5;
public:
int GetItem() {
return item;
};
void SetItem(int new_item) {
item = new_item;
};
};
过去,“item”曾经是该类的公共属性,可通过以下方式访问:
Test* t = new Test();
int item = t->item;
现在,我需要为检索“item”的方式添加新功能。例如:
int GetItem() {
// Some complicated code which changes "item"
return item;
};
如何保持相同的语法:
int item = t->item;
但这实际上有效:
int item = t->GetItem();
非常感谢任何帮助!
答案 0 :(得分:5)
您可以通过将int item = t.item;
定义为成员变量来使item
正常工作,该变量的类型是定义了自定义转换operator int()
的帮助程序类。此外,operator=(int new_value)
拦截设置操作。
你无法工作的是
int& item = t.item;
或
int* pitem = &t.item;
因为这两者都可以直接访问内存,而无需通过任何getter或setter。在创建引用或指针时,您甚至无法确定将有多少次访问,或者它们是读还是写。
答案 1 :(得分:1)
如果您的问题是基于您不想调用2个不同的函数进行设置和获取,则可以创建一个返回该成员引用的函数:
{
"error": {
"field": "amount",
"message": "The amount isn't correct - Sufficient credit."
}
}
如您所见,返回类型为int&而不是int。所以你可以这样使用这个功能
int& Item()
{
// Some complicated code which changes *items
return item;
}
答案 2 :(得分:1)
C ++是一种编译的非反射语言,即你不能只是“在访问元素时查找名称”,因为在二进制文件中,不再有名字了。
所以,不,你想要的是不可能的。 (至少不是没有限制 - 参见Ben Voigt的excellent answer;拥有一个“透明”的属性,实际上是一个吸气剂,肯定不值得你用它构建的陷阱 - )
另外,请不要让你的C ++成为Java只是为了拥有getter和setter - 如果它们实际上没有增加安全性,我真的没有看到使用它们的重点
答案 3 :(得分:0)
要扩展Ben Voight的答案,您可以定义一个代理模板,允许在没有样板的情况下进行此操作:
template <typename Return, typename Containing, Return (Containing::* func)()>
struct proxy
{
Containing& c;
proxy(Containing& c) : c(c) {}
operator Return() { return (c.*func)(); }
Return& operator=(const Return& r) { return (c.*set)() = r; }
};
然后定义“属性”
class c {
int y_;
int get_y() { std::cout << "Getting y" << std::endl; return y_; }
public:
proxy<int, x, &x::get_y> y;
c() : y(*this) {}
};
在客户端代码中
int main() {
c val;
val.y = 5;
std::cout << val.y << std::endl;
}