2015-09-18 69 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代码中的明确赋值并不重要,尽管初始化更清晰并且可能更有效。但是,在你无法默认初始化基类(你的案例)或成员的情况下 - 想到引用! - 你*需要*初始化。 –