当正确使用封装和“告诉,不要问” - 原则时,应该没有理由向对象询问信息。但是,我遇到了一种情况(如果这种设计本身很糟糕,请告诉我),我有一个对象,其成员变量指向类外的函数。
在我的应用程序的某个时刻,我的对象需要调用该函数,然后该函数应根据我的对象的状态进行操作。
这是一个示例类:
typedef void(*fptr)(Foo*);
class Foo {
public:
Foo(string name, fptr function);
void activate()
{
m_function(this);
}
private:
string m_name;
fptr m_function;
};
那就是类,现在开发人员可以像这样使用该类;
void print(Foo *sender)
{
cout << "Print works!" << endl;
}
int main(int argc, char **argv)
{
Foo foo("My foo", &print);
foo.activate();
// output: "Print works!"
}
这一切都很好,但是如果我想打印发件人的姓名怎么办?所有函数都是在类之外由其他开发人员定义的,因此无法访问私有变量。在C#
中,您可以只使用partial
关键字将方法添加到现有类。虽然这是不可能的C++
。
我可以忽略封装,并name
为该函数将来可能需要的所有其他属性创建一个 setter 和 getter。这是一个非常糟糕的解决方案,我基本上应该为我的类中的所有内容创建 setter 和 getter,因为该函数可以对我的对象做任何事情。除了封装的原因是什么,如果我想在我想忽略它的时候忽略它?
另一种解决方案是在其中包含所需属性的结构:
struct FooBar {
string name;
};
typedef void(*fptr)(FooBar);
void Foo::activate()
{
FooBar fb;
fb.name = m_name;
m_function(fb);
}
但这与不使用封装并没有太大区别,而且似乎也不是一个很好的解决方案。解决这个问题的最佳方法是什么?