如何从指向多态基类的指针复制/创建派生类实例?

Posted

技术标签:

【中文标题】如何从指向多态基类的指针复制/创建派生类实例?【英文标题】:How to copy/create derived class instance from a pointer to a polymorphic base class? 【发布时间】:2011-08-09 12:40:15 【问题描述】:

我为这种问题苦苦挣扎了很久,所以决定在这里问一下。

class Base 
  virtual ~Base();
;
class Derived1 : public Base  ... ;
class Derived2 : public Base  ... ;
...

// Copies the instance of derived class pointed by the *base pointer
Base* CreateCopy(Base* base);

该方法应该返回一个动态创建的副本,或者至少将对象存储在某个数据结构的堆栈中以避免“临时返回地址”问题。

实现上述方法的简单方法是在一系列 if 语句中使用多个 typeids 或 dynamic_casts 来检查每个可能的派生类型,然后使用 new 运算符。 还有其他更好的方法吗?

P.S.:我知道,使用智能指针可以避免这个问题,但我对简约的方法很感兴趣,没有一堆库。

【问题讨论】:

这似乎与此问题完全相同:***.com/questions/5148706/…。请参阅 Michael Anderson 那里接受的答案。 @Darhuuk:我不太确定关于重复的 SO 政策是什么,但这个问题有点不同。此处的 OP 询问了解决此问题的方法,而该问题的 OP 询问了克隆是否是一种好的 C++ 方法。这显然是相关的,只是不确定它是否“完全重复”。 @Itjax 很公平,只是给出的答案或多或少正是 OP 正在寻找的。虽然我猜你下面的答案更方便:)。 【参考方案1】:

您在基类中添加virtual Base* clone() const = 0; 并在派生类中适当地实现它。如果你的 Base 不是抽象的,你当然可以调用它的复制构造函数,但这有点危险:如果你忘记在派生类中实现它,你会得到(可能不需要的)切片。

如果您不想复制该代码,可以使用CRTP idiom 通过模板实现该功能:

template <class Derived>
class DerivationHelper : public Base

public:
  virtual Base* clone() const
  
    return new Derived(static_cast<const Derived&>(*this)); // call the copy ctor.
  
;

class Derived1 : public DerivationHelper <Derived1>  ... ;
class Derived2 : public DerivationHelper <Derived2>  ... ;

【讨论】:

【参考方案2】:

另一种方法是在每个派生类中实现的公共基础中使用纯虚拟CreateCopy() 方法。

【讨论】:

@David Doria:是的,除了 sn-p 大量泄漏内存。

以上是关于如何从指向多态基类的指针复制/创建派生类实例?的主要内容,如果未能解决你的问题,请参考以下文章

从指向基类的指针调用派生类的复制构造?

为啥指向基类的派生类指针可以调用派生类成员函数? [复制]

在 C++ 中将指向基类的指针传递给派生类的成员函数

如果继承类型受到保护,我可以使基类的指针指向派生对象吗? [复制]

包含指向派生模板类的基类指针的类的赋值运算符和复制构造函数

6多态性-3虚函数