如何从基类指针复制继承的类而不进行拼接

how to copy an inherited class from its base class pointer without splicing?

本文关键字:拼接 继承 基类 指针 复制      更新时间:2023-10-16

我有一些麻烦,试图创建一个从指针到它的基类的类的副本。下面的例子最能说明这一点:

#include <iostream>
#include <vector>
class Base {
  public:
    Base() { }
    virtual void test() { std::cout << "I am just the base classn"; }
};
class First : public Base {
  public:
    First() { }
    void test() { std::cout << "This is the First classn"; }
};
class Second : public Base {
  public:
    Second() { }
    void test() { std::cout << "This is the Second classn"; }
};
int main() {
  First *f = new First();
  Second *s = new Second();
  // First, I keep a vector of pointers to their base class
  std::vector<Base *> ptrs;
  ptrs.push_back(f);
  ptrs.push_back(s);
  ptrs[0]->test();    // Properly calls the implemented virtual class by inheritor
  ptrs[1]->test();    // Properly calls the implemented virtual class by inheritor
  // Now, I want to *copy* the class without it being spliced to just the base class
  // from the ptrs vector (not from 'f')
  First *f2 = new First(*ptrs[0]);
}
我最终得到的错误是:
test.cpp: In function ‘int main()’:
test.cpp:35: error: no matching function for call to ‘First::First(Base&)’
test.cpp:12: note: candidates are: First::First()
test.cpp:10: note:                 First::First(const First&)

是否有任何方法强制转换这个指针来复制完整的对象,而不仅仅是基类?或者我是否需要存储一个指向继承者的指针才能使其工作?

你可以这样做:

First *f2 = 0;
if ( typeid(*ptrs[0]) == typeid(First))
   f2 = new First(*dynamic_cast<First*>(ptrs[0]));

应该可以。

但是更好的方法是在基类中拥有clone()虚函数,并在派生类中实现它:

class Base 
{
  public:
    virtual ~Base() { } //virtual destructed added by me!
    virtual Base *clone() = 0;
};
class First : public Base 
{
  public:
    virtual First *clone() { /* implement it */ }  //Covariant return type
};

First *f2 = 0;
if ( typeid(*ptrs[0]) == typeid(First))
   f2 = ptrs[0]->clone(); //no need to use new

有两点需要注意:

    我在基类中添加了虚析构函数。请参阅本主题,了解您可能需要它的原因。
  • 我在派生类中为clone()使用了不同的返回类型。它被称为协变返回类型。
First *fx=(First*)ptrs[0];
First *f2 = new First(*fx);