2010-04-30 70 views
3

讓我們假設我有一個C++類,它已經正確實現了一個拷貝構造函數和一個overloaded =運算符。通過正確實現我的意思是他們工作和執行深層副本:這個構造函數是可以接受的練習嗎?

Class1::Class1(const Class1 &class1) 
{ 
    // Perform copy 
} 
Class1& Class1::operator=(const Class1 *class1) 
{ 
    // perform copy 
    return *this; 
} 

現在讓我們說我有這樣的構造,以及:

Class1::Class1(Class1 *class1) 
{ 
    *this = *class1; 
} 

我的問題是將上述構造是可以接受的做法?這是我繼承和維護的代碼。

+0

在我的代碼中,我計劃使用複製構造函數,而不是構造函數fyi。 – Robb 2010-04-30 16:46:42

回答

7

我會說「不」,有以下原因:

  • 傳統的拷貝構造函數接受它的參數作爲一個const參考,不作爲一個指針。
  • 即使您接受指針作爲參數,它確實應該是const Class1*來表示參數不會被修改。
  • 這個拷貝構造函數是低效(或將無法正常工作!),因爲Class1所有成員都默認初始化,然後使用operator=
  • operator=複製有同樣的問題;它應該接受一個引用,而不是一個指針。

operator=中「複製」複製構造函數的傳統方法是copy-and-swap idiom。我會建議以這種方式實施這個課程。

+0

非常好,我們會說。謝謝 – Robb 2010-04-30 16:51:24

+0

請記住,做複製和交換不能解決任何上述問題。特別是,所提到的低效率仍然存在。儘管如此,copy-and-swap在設計表現出強大的異常保證的類中很有用,所以這是一個很好的練習。 – 2010-04-30 17:43:48

2

就我個人而言,我認爲這不是好習慣。

對於構造函數,很難想象從指針到對象到對象本身的隱式轉換將會有用的地方。

沒有理由讓指針指向非const,並且如果您有可用的指向該類的指針,則不容易取消引用它,並且清楚地聲明您希望使用複製構造函數複製對象。

同樣,對於非標準賦值運算符,爲什麼在正確解引用的時候允許從指針分配指針更清晰和更習慣?

1

對象和指向對象的指針是兩個完全不同的東西。通常情況下,當你傳遞對象時,你期望它們將被複制(儘管如此,理想情況下,函數將盡可能地減少/消除不必要的副本,並使用const refs)。當你傳遞一個指針時,你不希望有任何複製發生。你正在傳遞一個指向特定對象的指針,並且根據代碼的不同,處理該特定對象並不是它的副本可能非常重要。

賦值運算符和需要指針類型構造 - 它可以用於隱式轉換特別構造 - 被真的要矇混過關的事情,站在創造意想不到的副本,它不僅可能是一個性能的機會很高問題,但它可能會導致錯誤。

我想不出有什麼好的理由,爲什麼你會想要在指向類型的指針和類型本身之間進行轉換 - 甚至是顯式的。內置的方法是解除對象的引用。我認爲可能有一些具體的情況,我不能想到這種事情可能是必要的或是一個好主意,但我真的懷疑它。當然,我強烈建議不要這樣做,除非你有這樣的具體和充分的理由。

2

我認爲比迄今爲止討論的更重要的問題是,您的非標準賦值運算符不會停止編譯器生成標準賦值運算符。既然你已經決定你需要創建一個賦值操作符(因爲你創建了拷貝構造函數,所以下注不錯),默認值幾乎肯定是不夠的。因此,對於幾乎任何人來說,這個類的用戶在看起來非常基本和標準的對象使用過程中可能會成爲這個問題的犧牲品。

相關問題