2011-12-21 7 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])); 

動作する必要があること。

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()仮想関数を持っており、それに派生クラスを実装することです
  • 私は基本クラスに仮想デストラクタを追加しました。 、おそらくが必要な理由を知るには、this topicを参照してください。
  • 派生クラスでclone()に異なる戻り値の型を使用しました。それはcovariant return typeと呼ばれます。
1
First *fx=(First*)ptrs[0]; 
First *f2 = new First(*fx); 
関連する問題