2011-10-21 36 views
2

考慮我創建兩類對象:清分基類對象的derieved類

BaseClass B; 
DerievedClass D; 

,然後我在做什麼:

B=D; 
D=B; 

哪些是合法的,以及爲什麼。這是C++相關Job的訪問者提出的一個問題。我主要知道B = D;將是有效的(對象切片);但它是這樣,D = B;只有在B有默認構造函數時纔有效?是的,那爲什麼?

回答

6
B=D; 
D=B; 

第一行將始終編譯。第二行可能會或可能不會編譯,因爲它完全取決於您編寫每個類的方式。答案的其餘部分將闡明它。請繼續閱讀。


是它使得d = B;只有在B有默認構造函數時纔有效?

D=B號將是有效僅當d定義operator=這需要B作爲參數。

Derived & operator=(const Base &base); //member of Derived 

Base B; 
Derived D; 
D = B;  //allowed - assignment 

或者,如果你這樣做,在D初始化,那麼它會有效,僅當D一個構造函數接受B作爲參數。

Derived(const Base &base); //a constructor of Derived 

Base B; 
Derived D = B; //allowed - initialization 

或者B定義了一個用戶定義的轉換到D

operator Derived(); //member of Base 

Base B; 
Derived D = B; //allowed  - initialization 
D = B;   //also allowed - assignment 
+0

而且'D = B'情況通常不是你想要的。可能會出現這種情況,但它們很少見(這就是爲什麼你必須做一些明確的事情才能編譯它)。 –

+1

另外,三種方式的+1做這種轉換。 –

0

納瓦茲是對的。 B = D是合法的,因爲D是BaseClass的一個實例,並且將通過編譯器生成的BaseClass的拷貝構造函數接受。

BaseClass::BaseClass(const BaseClass& other) { ... } // Implicit 

此拷貝構造將由DerivedClass被繼承,但這樣做當d = B,則編譯器將尋找一個DerivedClass(常量的BaseClass &)方法,至極不存在。

DerivedClass::DerivedClass(const DerivedClass& other); // Implicit 
DerivedClass::BaseClass(const BaseClass& other);  // Inherited 
DerivedClass::DerivedClass(const BaseClass &other); // Not defined! 
0

沒有看到類的實現,你不能假定任何兩個都會編譯!

第一種情況:B=D

這將彙編,除非B的=運算符已被重載,在這種情況下,即使B=B 可能屬於違法行爲。所有你可以說的是,如果B=B是合法的,那麼B=D也是合法的,因爲DBaseClass類的有效實例。

第二種情況:D=B

這一個已被正確的納瓦茲討論。但總之,你需要明確地允許它。您可以:

  1. 定義相等操作:

    DerivedClass::operator=(const BaseClass& copy)

  2. 定義一個明確的轉換操作符:

    BaseClass::operator DerivedClass() const

  3. 添加一個構造函數中DerivedClass接受一個BaseClass

    DerivedClass::DerivedClass(const BaseClass&)

注意,在第二和第三方案不應該共同existe,而第三個一般應是優選的。只有在您無法修改類或者您想要轉換爲不是類的類型的情況下,轉換運算符才存在。