考慮我創建兩類對象:清分基類對象的derieved類
BaseClass B;
DerievedClass D;
,然後我在做什麼:
B=D;
D=B;
哪些是合法的,以及爲什麼。這是C++相關Job的訪問者提出的一個問題。我主要知道B = D;將是有效的(對象切片);但它是這樣,D = B;只有在B有默認構造函數時纔有效?是的,那爲什麼?
考慮我創建兩類對象:清分基類對象的derieved類
BaseClass B;
DerievedClass D;
,然後我在做什麼:
B=D;
D=B;
哪些是合法的,以及爲什麼。這是C++相關Job的訪問者提出的一個問題。我主要知道B = D;將是有效的(對象切片);但它是這樣,D = B;只有在B有默認構造函數時纔有效?是的,那爲什麼?
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
納瓦茲是對的。 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!
沒有看到類的實現,你不能假定任何兩個都會編譯!
第一種情況:B=D
這將彙編,除非B的=運算符已被重載,在這種情況下,即使B=B
可能屬於違法行爲。所有你可以說的是,如果B=B
是合法的,那麼B=D
也是合法的,因爲D
是BaseClass
類的有效實例。
第二種情況:D=B
這一個已被正確的納瓦茲討論。但總之,你需要明確地允許它。您可以:
定義相等操作:
DerivedClass::operator=(const BaseClass& copy)
定義一個明確的轉換操作符:
BaseClass::operator DerivedClass() const
添加一個構造函數中DerivedClass
接受一個BaseClass
:
DerivedClass::DerivedClass(const BaseClass&)
注意,在第二和第三方案不應該共同existe,而第三個一般應是優選的。只有在您無法修改類或者您想要轉換爲不是類的類型的情況下,轉換運算符才存在。
而且'D = B'情況通常不是你想要的。可能會出現這種情況,但它們很少見(這就是爲什麼你必須做一些明確的事情才能編譯它)。 –
另外,三種方式的+1做這種轉換。 –