2011-12-21 73 views
1

我在尝试从指向其基类的指针创建类的副本时遇到了一些麻烦。如何从基类指针复制继承类而不拼接?

#include <iostream> 
#include <vector> 

class Base { 
    public: 
    Base() { } 
    virtual void test() { std::cout << "I am just the base class\n"; } 
}; 

class First : public Base { 
    public: 
    First() { } 
    void test() { std::cout << "This is the First class\n"; } 
}; 

class Second : public Base { 
    public: 
    Second() { } 
    void test() { std::cout << "This is the Second class\n"; } 
}; 

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&) 

有没有什么办法来施放此指针复制完整的反对,而不仅仅是基类最好是通过这个例子说明?或者我需要存储一个指向继承者的指针来完成这个工作?

回答

3

你可以这样做:

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 

要注意两点:

  • 我已经添加了虚拟析构函数到基类。看到this topic知道你为什么可能需要它。
  • 我在派生类中使用了clone()的不同返回类型。它被称为covariant return type
1
First *fx=(First*)ptrs[0]; 
First *f2 = new First(*fx);