仅使用基类指针复制派生实体(没有详尽的测试!) - C++

geo*_*nes 36 c++ inheritance pointers copy-constructor

鉴于由派生类的继承过多基类,这需要您通过基类指针,每个实体管理这些程序结构.当只知道基类指针时,是否有一种简单的方法来复制整个派生对象?

环顾四周似乎可能(如果非常繁琐)使用dynamic_cast调用来检查基类指针是否可以作为适当的派生类进行转换,然后使用派生类的复制构造函数复制它.然而,这并不是一个真正的最佳解决方案,部分原因是由于过度使用了dynamic_cast,而且它会让人感到头疼,难以维持和扩展.

我遇到的另一个更优雅的解决方案如下:

class Base
{
public:
   Base(const Base& other);
   virtual Base* getCopy();
   ...
}

class Derived :public Base
{
   Derived(const Derived& other);
   virtual Base* getCopy();
   ...
}

Base* Base::getCopy()
{
   return new Base(*this));
}

Base* Derived::getCopy()
{
   return static_cast<Base*>(new Derived(*this));
}
Run Code Online (Sandbox Code Playgroud)

然后通过调用getCopy()指向任何派生对象的Base类指针,仍然可以返回一个基类指针,但也复制了整个派生对象.这种方法感觉更易于维护,因为它只需要getCopy()在所有派生类中使用类似的函数,并且不需要针对所有可能的派生对象进行测试.

从本质上讲,这是明智的吗?或者有更好,更简洁的方式吗?

tem*_*def 38

这种方法是复制多态对象的首选方法,因为它减轻了确定如何将任意类型的对象复制到该对象的责任,而不是在编译时尝试确定它.更一般地说,如果你不知道基类指针在编译时指向什么,你就不可能知道为获得正确的副本而需要执行的许多潜在代码段中的哪一段.因此,任何工作解决方案都需要动态选择代码,虚拟功能是一种很好的方法.

对您的实际代码有两条评论.首先,C++继承允许覆盖基类成员函数的派生类使派生函数返回比基类版本更具体的类型的指针.这称为协方差.例如,如果是基类函数

virtual Base* clone() const;
Run Code Online (Sandbox Code Playgroud)

然后派生类可以将其覆盖为

virtual Derived* clone() const;
Run Code Online (Sandbox Code Playgroud)

这将完美无缺.例如,这允许您拥有如下代码:

Derived* d = // something...
Derived* copy = d->clone();
Run Code Online (Sandbox Code Playgroud)

如果没有协变过载,那将是不合法的.

另一个细节 - 在您拥有的代码中,您明确指出static_cast了代码中基本指针的派生指针.这是完全合法的,但没有必要.C++将隐式地将派生类指针转换为基类指针而不使用强制转换.但是,如果使用协变返回类型的想法,则不会出现这种情况,因为返回类型将与您要创建的对象的类型相匹配.