当前位置 : 主页 > 编程语言 > c++ >

c – 传递基类指针

来源:互联网 收集:自由互联 发布时间:2021-06-23
场景:我有以下定义的类. class Baseclass { };class DerivedTypeA : public Baseclass { };class DerivedTypeB : public Baseclass { };// ... and so on ...class Container{ listBaseclass* stuff; listDerivedTypeA* specific_stuff;// ... in
场景:我有以下定义的类.

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"
}
网友评论