c – 传递基类指针
作者:互联网
场景:我有以下定义的类.
class Baseclass { };
class DerivedTypeA : public Baseclass { };
class DerivedTypeB : public Baseclass { };
// ... and so on ...
class Container
{
list<Baseclass*> stuff;
list<DerivedTypeA*> specific_stuff;
// ... initializing constructors and so on ...
public:
void add(Baseclass * b)
{
stuff.add(b);
}
void add(DerivedTypeA * a)
{
stuff.add(a);
specific_stuff.add(a);
}
};
class ContainerOperator
{
Container c;
// ... initializing constructors and so on ...
public:
void operateOnStuff(Baseclass * b)
{
// This will always use "void add(Baseclass * b)" no matter what object b really is.
c.add(b);
}
};
// ...
containerOperator.operateOnStuff(new DerivedTypeA());
所以,我想要做的是在Container中以某种特殊方式处理某个派生类.
问题:从不调用void add(DerivedTypeA * a).我显然做错了什么.做我想做的事情的正确方法是什么?
解决方法:
C中的重载分辨率发生在编译时,而不是运行时.解决这类问题的“通常”方法是使用Visitor pattern.
您可以通过使用CRTP实现Visitor来减少样板复制粘贴的数量.
如果使用CRTP for Base :: accept,则无需在派生类中再定义它.
这是一个与你类似的程序,但有点简单:
#include <iostream>
class Base; class Derived;
struct Operation {
void add(Base *b) {
std::cout << "Base\n";
}
void add(Derived *b) {
std::cout << "Derived\n";
}
void visit(Base *b); // need to define this after Base class
};
struct Base {
virtual ~Base() {}
virtual void accept(Operation &o)
{
o.add(this);
}
};
void Operation::visit(Base *b) {
b->accept(*this);
}
struct Derived : public Base {
void accept(Operation &o)
{
o.add(this);
}
};
int main() {
Operation o;
Base b;
Derived d;
Base *ptrb = &b;
Base *ptrd = &d;
o.add(ptrb); // These two print "Base"
o.add(ptrd);
o.visit(ptrb); // "Base"
o.visit(ptrd); // "Derived"
}
标签:c,inheritance,design-patterns,class-design 来源: https://codeday.me/bug/20190730/1583821.html