我创建了一个这样的类
class myClass {
public:
int addMeOne;
void Invoked() { .... }
};
我创建了它的一个对象,并用它通过引用将它发送到我程序的所有其他模块。每个人都习惯将addMeOne变量增加1。有些甚至曾经用过两次,但这不是重点。
有了这个,现在我希望每当有人改变addMeOne时,我的函数Invoked()应该被调用。
请注意,正确的策略是我应该允许addMeOne通过某些函数暴露在外部,并且在我可以调用Invoked的函数内部。但是,界面现在无法更改,因为现在它已暴露给所有其他界面,因此不应修改。我怎么能纠正这个。 ?
答案 0 :(得分:0)
你必须创建一个方法,将值赋给addMeOne
变量,这称为setter方法,并将变量本身设为私有。
我相信在更改整数变量时无法触发函数。
将更改接口的一个替代方案,但不会要求更改外部代码是定义一个模仿整数行为的类,即实现{ {1}}等,并将operator++
更改为此类型。
答案 1 :(得分:0)
您需要了解封装。如果没有为addMeOn
提供锁定的getter / setter接口,则无法保证对其使用的控制。
不要害怕改变界面。对于任何使用它进行更改的人来说,这不是一项大任务,他们应该清楚你在改变它时所做的是为他们的利益提供价值。
答案 2 :(得分:0)
实际上,可能值得告诉所有客户使用方法而不是公共变量。您需要更改类,客户端或两者。
没有办法绕过它。再做一次,做得对。点击。
有一些技巧:一旦你公开一个成员变量,你可以做的一件事就是将int addMeOne
替换为一些具有相同名称但不同类型的其他变量。 countedint addMeOne
。您必须编写的countedint
类,使其行为类似于int,但赋值,增量等也会计算它们的使用次数。例如
countedint & operator ++(){
m_value++;
m_number_of_uses++;
return *this;
}
countedint & operator --(){
m_value--;
m_number_of_uses++;
return *this;
}
你可能还需要有一个转换操作符到int,你也可以计算那里的使用次数。
答案 3 :(得分:0)
您应该保留此类的ABI,还是仅保留其客户端使用的语法?
如果您可以更改addMeOne
的类型,保留编写addMeOne++
等的能力,则可以为其定义类及其相关运算符 - 然后使addMeOne
成为此实例类。当然,现在addMeOne
运算符可以执行任何操作 - 包括调用某些MyClass
成员函数。
伪代码:
class Proxy
{
public:
Proxy(YourClass *parent) : parent_(parent), value_(0)
{}
void operator++()
{
++value_;
// doAnything with parent_
}
// accessors, cast operators etc...
private:
YourClass *parent_;
int value_;
};
class YourClass
{
public:
YourClass() : addMeOne(this)
{}
Proxy addMeOne;
};
答案 4 :(得分:0)
使用可以将addMeOne
转换为代理。
class myClass
{
class addMeOneProxy
{
public:
addMeOneProxy(myClass &s) : parent(s) {}
// This gets called whenever something tries to use the addMeOne
// member variable as an integer.
operator int() const
{
return parent.addMeOne;
}
// This gets called whenever something assigns a value to addMeOne.
int operator=(int val)
{
parent.Invoked();
return val;
}
// You could also implement an operator++ or whatever else you need.
private:
myClass &parent;
};
public:
void Invoked();
addMeOneProxy addMeOne;
};
当然,如果您决定在某些时候将Invoked()设为私有,则需要将myClass设为addMeOneProxy的友元类,以便addMeOneProxy可以调用Invoked成员函数。
我当然同意其他评论者的说法,你应该真正拥有getter和setter函数,但我也理解开发人员通常只有有限的权力来控制和改变他们所居住的世界。所以,代理就是你如何能够如果你不能或不允许改变世界,那就去做吧。