2015-09-18 114 views
0

我創建了三個類:Square,Rectangle和Polygon。 Square從Rectangle繼承,Rectangle從Polygon繼承。未調用超類構造函數的多級繼承

問題是,無論何時我調用Square構造函數,Rectangle構造函數都會被調用,並且出現錯誤。我該如何解決這個問題?

#include <iostream> 
using namespace std; 

// Multilevel Inheritance 

class Polygon 
{ 
protected: 
    int sides; 
}; 

class Rectangle: public Polygon 
{ 
protected: 
    int length, breadth; 
public: 
    Rectangle(int l, int b) 
    { 
     length = l; 
     breadth = b; 
     sides = 2; 
    } 
    void getDimensions() 
    { 
     cout << "Length = " << length << endl; 
     cout << "Breadth = " << breadth << endl; 
    } 

}; 

class Square: public Rectangle 
{ 
public: 
    Square(int side) 
    { 
     length = side; 
     breadth = length; 
     sides = 1; 
    } 
}; 

int main(void) 
{ 
    Square s(10); 
    s.getDimensions(); 
} 

如果我註釋掉Rectangle構造函數,一切正常。但我想有兩個構造函數。有什麼我可以做的嗎?

+1

'類方形:公共Rectangle'哦... – SingerOfTheFall

+0

你不叫矩形直接構造所以默認的構造函數將被調用......然而,沒有默認的構造函數,你必須定義它或直接調用你的構造函數。 – Melkon

+0

正方形/矩形實際上在其他地方作爲反對繼承的示例進行了討論。人們可能會試圖反轉繼承關係,這也會導致其他問題。也就是說,在邊上調用Rectangles ctor:'Square(int side):Rectangle(side,side){...}'哦,Petr在關於Square的ctor的回答中有一點。 –

回答

2

您不應該在派生類構造函數中設置基類的成員。相反,顯式調用基類構造函數:

class Polygon 
{ 
protected: 
    int sides; 
public: 
    Polygon(int _sides): sides(_sides) {} // constructor initializer list! 
}; 

class Rectangle: public Polygon 
{ 
protected: 
    int length, breadth; 
public: 
    Rectangle(int l, int b) : 
     Polygon(2), // base class constructor 
     length(l), 
     breadth(b) 
    {} 
}; 

class Square: public Rectangle 
{ 
public: 
    Square(int side) : Rectangle(side, side) 
    { 
     // maybe you need to do this, but this is a sign of a bad design: 
     sides = 1; 
    } 
}; 
+0

那麼,我應該在你使用'sides = 1'的地方使用Polygon(1)嗎? – Lokesh

+1

@Lokesh,不,你可以只調用一個_direct_基類的構造函數,在這裏是'Rectangle'。您不能直接從'Square'構造函數調用'Polygon'構造函數。然而,你對'sides'的處理是一種糟糕的設計:如果你的'Square'是'Rectangle'的子類,那麼你可以說'Square' [是](https://en.wikipedia.org/wiki/Is-a)'矩形'。因此,我期望大多數屬於「矩形」的屬性也適用於「Square」。其中一個屬性似乎是'sides == 2',所以我期望'Square'也有'sides == 2'。 (續) – Petr

+0

......實際上,當你的'矩形'和'方形'有不同的'sides'時,肯定會出現這樣的情況,但只給出有問題的代碼,很難提出一個特定的解決方案。你可能想爲此提出一個單獨的問題。解釋你想達到什麼目的,特別是(但不僅僅是!)爲什麼你需要''矩形'和'方形''不同的'邊',並且可能你會被告知更好的設計。 – Petr

2

構造應該是

Square(int side) : Rectangle(side, side) { sides = 1; } 

Rectangle沒有默認構造函數。

+0

我從來沒有見過這種語法。 「:」在這裏做什麼? – Lokesh

+1

這是這個類的成員的初始化列表。 – Robinson

+0

通常這樣初始化成員或通過ctor代碼中的明確賦值並不重要,儘管初始化更清晰並且可能更有效。但是,在你無法默認初始化基類(你的案例)或成員的情況下 - 想到引用! - 你*需要*初始化。 –