gpt4 book ai didi

c++ - 对象需要让函数访问它的所有数据

转载 作者:搜寻专家 更新时间:2023-10-31 00:39:04 24 4
gpt4 key购买 nike

当正确使用封装和“告诉,不要问”原则时,应该没有理由向对象询问信息。但是,我遇到过这样一种情况(如果这种设计本身很糟糕,请告诉我)我有一个对象,其中的成员变量指向类外部的函数。

在我的应用程序的某个时刻,我的对象需要调用该函数,然后该函数应根据我的对象的状态进行操作。

这是一个示例类:

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!"
}

一切正常,但如果我想打印发件人的姓名怎么办?所有函数都是在类之外由其他开发人员定义的,因此无法访问私有(private)变量。在 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);
}

但这与不使用封装没有太大区别,而且似乎也不是一个太好的解决方案。解决此问题的最佳方法是什么?

最佳答案

我会让 activate() 成为一个抽象方法,并且所有类的属性都受到保护。此外,也不需要 fptr:

class Foo {
public:
Foo(string name);
virtual void activate() = 0;
protected:
string m_name;
};

现在当有人想使用你的类时,他只是继承了他自己的类:

class MyFoo : public Foo {
public:
MyFoo(string name);
virtual void activate()
{
cout << m_name << " says: Hello World!" << endl;
}
};

int main(int argc, char **argv)
{
MyFoo foo("My foo");
foo.activate();
// output: "My Foo says: Hello World!"
}

如果您需要许多具有不同功能的Foo,只需继承多个类而不是声明多个函数。


编辑:不是为每个不同的 Foo 实例继承一个新类,您可以使用所有不同的方法为所有实例继承一个类。现在 activate 剩下的就是决定调用哪个方法;为此使用 enum:

enum MyFooFunction {
printName,
printHello
};

class MyFoo : public Foo {
public:
MyFoo(string name, MyFooFunction function);
void printName() { cout << m_name << endl; }
void printHello() { cout << "Hello!" << endl; }
virtual void activate()
{
switch(m_function) {
case printName:
printName();
break;
case printHello:
printHello();
break;
}
}
protected:
MyFooFunction m_function;
};

关于c++ - 对象需要让函数访问它的所有数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16939703/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com