2014-07-11 161 views
8

我發現自己正在做的一件常見事情是製作「幾乎默認」的複製構造函數和賦值運算符。也就是說,我發現自己在編譯器提供的複製和賦值操作符適用於大多數數據成員的情況下,但是有一個特定的數據成員需要以不同的方式處理。這意味着我必須顯式創建一個拷貝構造函數/賦值運算符,包括明確列出所有具有簡單複製語義的數據成員。這對於有相當數量的數據成員的類,或稍後在添加成員變量但未添加到複製構造函數/賦值運算符時會變得煩人。C++中的「幾乎默認」複製構造函數(&賦值運算符)

有什麼方法可以告訴C++編譯器:顯式聲明的拷貝構造函數/賦值運算符應該像隱式運算一樣運行,除了一些額外的代碼之後運行嗎? (並且是C++ 98兼容的語法,還是需要C++ 11或C++ 14支持?)

+16

爲該數據成員實現適當的RAII包裝,然後默認的構造函數將適用於所有內容。 –

回答

8

如果您可以按照Igor Tandetnik的建議,在適當的RAII包裝中分離特定的處理:go爲了那個原因。

如果您仍然需要在複製構造函數和/或賦值運算符中進行特定處理(例如將對象創建/賦值註冊到容器或日誌中),則可以將可以構建/分配的默認拷貝的數據成員分組一個單獨的類,你作爲一個基類或數據成員使用,您處理,因爲複合材料,即:

struct x_base { 
    int a,b,c,d; 
    std::string name; 
}; 

struct x : x_base { 
    x(const x& other) 
     : x_base(other) 
    { 
     descr = "copied "; 
     descr += name; 
     descr += " at "; 
     descr += CurrentTimeAsString(); 
     std::cout << descr << "\n"; 
    } 
    void operator = (const x& other) 
    { 
     x_base::operator =(other); 
     descr = "assigned "; 
     descr += name; 
     descr += " at "; 
     descr += CurrentTimeAsString(); 
     std::cout << descr << "\n"; 
    } 
    std::string descr; 
}; 

當您以後添加數據成員不需要特定的處理,你可以簡單地將它們添加到x_base 。

+1

這利用了這樣一個原則,即非工會類的隱式定義拷貝構造函數執行其基礎和成員的成員副本 (Standard C++,sect 12.8 pt 15)。但請注意,這對成員複製完成的順序有一些限制。 – Christophe

相關問題