来自纯“C”,我是一个 C++ 新手,对 OO 开发或多或少是新手,因此我提前为我对以下主题的“幼稚”观点道歉。在下文中,我试图以抽象的方式描述我的问题(我的真实类是不同的)。代码部分可能无法编译,应仅被视为“想法”。
我有几个类,继承自一个基类:
class Base
{
};
class Derived1 : Base
{
};
class Derived2 : Base
{
};
class Derived3 : Base
{
};
此外, vector 包含指向派生类实例的指针:
std::vector<Base *> collection;
现在我想提供这个类方案供其他用户使用。 问题:当用户遍历集合时,他/她如何知 Prop 体的类类型?为派生类提供虚拟成员函数不是一个好的选择,因为我事先不知道用户想要做什么。
他/她应该使用 dynamic_cast(...) 来获取具体类吗?不太好...
经过几个小时的思考,我最终得出了以下“解决方案”,但我不确定这是真的好还是完全是胡说八道:
为用户对象定义接口(interface),对上述类进行操作:
class Derived1;
class Derived2;
class Derived3;
class AbstractUserOperation
{
virtual void call(Derived1 * cl) = 0;
virtual void call(Derived2 * cl) = 0;
virtual void call(Derived3 * cl) = 0;
};
用户基于该接口(interface)定义一个具体类,以实现他/她对我的派生类的每种可能类型的期望操作:
class ConcreteUserOperation : AbstractUserOperation
{
virtual void call(Derived1 * cl)
{
...
}
virtual void call(Derived2 * cl)
{
...
}
virtual void call(Derived3 * cl)
{
...
}
};
我自己的类(class)和以前一样,由“评估”扩展:
class Base
{
virtual void evaluate(AbstractUserOperation* o) = 0;
};
class Derived1 : public Base
{
void evaluate(AbstractUserOperation *o)
{
o->call(this);
}
};
class Derived2 : public Base
{
void evaluate(AbstractUserOperation *o)
{
o->call(this);
}
};
class Derived3 : public Base
{
void evaluate(AbstractUserOperation *o)
{
o->call(this);
}
};
用法如下:
std::vector<Base *> collection;
ConcreteUserOperation o; // a user defined class, doing whatever with x
x = collection[i];
x->evaluate(&o); // call user defined operation o on x
当然,这有点“复杂”,但是,至少,一切都取决于用户定义具体的操作类,这与我的类方案完全分开。
从架构的角度来看,这种方法是否可以接受??? 希望这对这里的所有专家来说都不会太无聊 ;-)
非常感谢, 迈克尔
最佳答案
我不是这个访问者概念的专家,但我使用类似的代码并且我一直将其视为回调。我认为,如果您允许调用 Derived 的评估并使用 std::function 作为回调参数,您甚至不需要为 ConcreteUserOperation 定义接口(interface)。然后你甚至应该能够作为访问者插入 lambda。示例代码:
#include <functional>
struct Base {};
struct Derived : public Base
{
void evaluate(std::function<void(const Derived&)> callback) const
{
callback(*this);
}
int foo = 42;
};
int main()
{
Derived d;
d.evaluate([](const Derived& d){std::cout << d.foo << std::endl;});
}
关于c++ - 关于 C++ 继承的初学者架构主题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22311533/