2015-07-21 73 views
1

我有一個關於良好C++風格的問題: 我想寫一個類「MyClass」,它有一個或一些指針作爲成員,MyClass能夠分配內存到這個指針。我想使用隱式賦予的默認複製構造函數(以及默認的assignement運算符)來複制MyClass的實例,以便只複製指針並且新對象共享初始對象所擁有的數據分配。記住只能管理共享內存的原始對象

我的想法是禁止複製的對象(與拷貝構造函數或賦值操作符創建)來釋放內存(以及分配內存以成員指針)。爲了複製的對象和原始對象(通過構造函數創建的)之間distinguesh,我想用下面的代碼:

class MyClass 
{ 
public: 
     MyClass(): originalPtr(this) { data = new char[100000]; } 
     ~MyClass() { if(originalPtr == this) delete[] data; } 
private: 
     MyClass *originalPtr; 
     char *data; // shared data (not copiable) 
     char otherFeatures[10]; // individual data (copiable) 
}; 

將會對這種解決(使用與this終場前的比較)的好作風這種一個目的(例如通過值調用來解析一個對象)還是有風險的?當然,我認爲原始對象的存在時間通常比複製的對象長。

謝謝!

+5

如果原始文件總是比副本壽命更長,爲什麼要複製而不是分發引用? –

+0

爲了提供副本的個人數據(由「otherFeatures」暗示)。 –

+2

爲什麼不使用'shared_ptr'或類似的東西? – Petr

回答

1

不,這是一個壞主意。如果這些指針被多個實例共享,那麼應該是最後一個要去死的那個,而不是原來的那個。這個不同之處在於,原來的那個可能不是那個會死的人,這會導致所有其他人指向垃圾。即使你認爲它是最後一個死亡,你需要認識到一個階級的內部運作不應該依賴於外部假設。也就是說,班級無法保證其餘的實施過程如何管理其生命週期,所以不應該做出假設。

在這種情況下,您應該跟蹤對您的數據的引用。基本的想法是跟蹤你有多少個副本。只要該計數達到零,您就可以自由釋放該內存;最後一個副本剛剛死亡。幸運的是,STL already provides such an implementation。這些被稱爲Smart Pointers。還有其他的,例如std::unique_ptr,它通過確保數據僅由單個實例擁有而相反。

0

確定,假定一般的情況下,其中原始對象不最後死亡。我喜歡這個想法來統計實例。例如,可以使用這樣的概念:

class MyClass 
{ 
public: 
    MyClass(): countOfInstances(new int()) 
    { 
     ++*countOfInstances; 
     data = new char[100000]; 
    } 

    ~MyClass() 
    { 
     --*countOfInstances; 
     if(!countOfInstances) 
     { 
      delete[] data; 
      delete countOfInstances; 
     } 
    }  

    MyClass(const MyClass &other) // analogous for the assignment operator 
    { 
     countOfInstances = other.countOfInstances; 
     data = other.data; 
     otherFeatures = other.otherFeatures; 
     ++*countOfInstances; 
    } 

private: 
    int *countOfInstances; 
    char *data; // shared data (not copiable) 
    char otherFeatures; // individual data (copiable) 

};

在這裏,人們還應該確保共享內存允許進行復印前,完全分配。

+0

爲什麼不使用智能指針並節省麻煩? –