如何获得继承已知类的未知类的副本

How to achieve a copy of an unknown Class which inherits a known class

本文关键字:副本 未知 何获得 继承      更新时间:2023-10-16

我需要一个不同类实例的数组(这里:B),它们都共享相同的基类(这里:A)。
实例应该作为指针存储,因为它们在其他地方被引用(这里没有显示)。
我试着这样做:

class A {
public:
  A() {}
};
class B : public A {
  int m_magicValue;
public:
  B() : A() , m_magicValue(4711){}
  int getMagicValue() { return m_magicValue; }
};
class Manager {
  std::vector<A*> m_array;
public:
  Manager() {}
  virtual ~Manager() {
      for( size_t i=0; i<m_array.size(); i++ )
          delete m_array[i];
      m_array.clear();
  }
  void addA( const A& a ) {
    // here A is copied - here the problem occurs
    m_array.push_back( new A(a) );
//    createSomeReferences( m_array.back() );
  }
  A& getA( size_t idx ) {
    return *m_array[idx];
  }
};
int main() {
  B b;
  Manager manager;
  manager.addA(b);
  B& copiedB = (B&) manager.getA(0);
  int magic = copiedB.getMagicValue(); // magic is some random stuff instead of 4711!
  return 0;   
}

Manager不知道任何关于B类的事情,它只知道a类。
在addA()中发生了一件有趣的事情:这里它试图复制B并在数组中存储一个指针。
但正如预期的那样,它并不像预期的那样工作;-)copiedB.getMagicValue ();返回一个随机值。

原因比较清楚:使用A的复制构造函数而不是B的复制构造函数,因此只复制A的部分。

现在我的问题是:有没有一种好方法来实现这样的复制,它继承了整个类的层次结构,即使只有基类是已知的?

您需要一个虚拟的"克隆"函数(有时通俗地称为"虚拟复制构造函数"):

struct A
{
    virtual ~A() { }
    virtual A * clone() const = 0;
};

struct B : A
{
    virtual A * clone() const
    {
        return new B(*this);
    }
};

用法:

void addA(A const & a)
{
    insert(a.clone());
}

使用原始指针是非常愚蠢的,但是,最好让克隆函数以及容器在std::unique_ptr<A>上键入(代码在其他方面几乎相同)。

(你现在可能会问自己,"为什么没有一个版本的unique_ptr已经做了深度,虚拟克隆,也许叫value_ptr<A> ?这个问题问得好