2016-11-13 8 views
-1

は、以下のクラスを検討コピーするために使用される基本クラスのポインタからの属性を変更します:コピーされたオブジェクトは、それが

class Base { 
public: 
    ... // include virtual destructor and rest of methods 
    virtual void changeField(int val) = 0; 
    virtual Base * clone() const = 0; 
}; 

class Derived: public Base { 
    int x; 
public: 
    ... // include its destructor and rest of its methods 
    void changeField(int val) { x = val; } 
    Derived * clone() const { return new Derived(*this); } 
}; 

を私はDerivedオブジェクトを指す既存のBase *ポインタbpがあるとします。次にbp->clone()を呼び出してコピーを作成し、結果のオブジェクトのポインタをBase *ポインタcopyPointerに格納します。

copyPointerchangeFieldに変更すると値は変更されますが、元のオブジェクトのフィールドも変更されています。どうしてこれなの?これを防ぐために私は何ができますか?最初から全く新しいオブジェクトを作成する必要がありますか?

編集:ここではは私が

int main() { 
    try { 
     Base * copyPointer = bp->clone(); 
     copyPointer->changeField(5); 
     cout << copyPointer->print() << endl; //prints the field of Derived 
     delete copyPointer; 
     } 
     catch (exception& e) { // I also have an Exception class in my code 
     cout << e.what() << endl; 
     } 
} 
+0

はあなたが記述挙動を示すコードを表示します。 – rubenvb

+0

[mcve]を投稿してください。 – PaulMcKenzie

+0

例で更新しました – CSishard

答えて

1

あなたの仮定を説明したシナリオを実装している私の主な機能である、copyPointerの機能changeField()は、元のオブジェクトを変更することを、間違っています!

私はあなたの例を詳述:

#include <iostream> 
using std::cout; 
using std::endl; 

class Base { 
    public: 
    // include virtual destructor and rest of methods 
    virtual void changeField(int val) = 0; 
    virtual Base * clone() const = 0; 
    virtual int print() const =0; 
}; 

class Derived: public Base { 
    int x; 
    public: 
    // include its destructor and rest of its methods 
    Derived(int i):x(i) {} 
    void changeField(int val) { x = val; } 
    Derived * clone() const { return new Derived(*this); } 
    int print()const { return x; } 
}; 
int main() { 
    Base* bp =new Derived(3); 
    cout <<bp->print() <<endl; 
    Base * copyPointer = bp->clone(); 
    copyPointer->changeField(5); 
    cout <<copyPointer->print() <<endl; //prints the field of Derived 
    cout <<bp->print() <<endl; 
} 

、出力は次のとおりです。

3 
5 
3 
+0

アドバイスする価値:派生クラスでキーワード 'override'を使う – Christophe

関連する問題