2015-01-12 82 views
0

多重继承一个基类

这里是我的榜样test.hpp(简体):

class House { 
    private: 
     int nWindows; 
    public: 
     House(int nWindows); 
     int getNumberOfWindows(); 
}; 

class PaintedHouse : public virtual House { 
    private: 
     int colorCode; 
    public: 
     PaintedHouse(int nWindows, int colorCode); 
     int getColorCode(); 
}; 

class OccupiedHouse : public virtual House { 
    private: 
     int nPeople; 
    public: 
     OccupiedHouse(int nWindows, int nPeople); 
     int getNumberOfPeople(); 
}; 

class PaintedOccupiedHouse : public PaintedHouse, OccupiedHouse { 
    public: 
     PaintedOccupiedHouse(int nWindows, int colorCode, int nPeople); 
}; 

而且test.cpp

#include "test.hpp" 

House::House(int nWindows) { this->nWindows = nWindows; } 
int House::getNumberOfWindows() { return this->nWindows; } 

PaintedHouse::PaintedHouse(int nWindows, int colorCode) : House(nWindows) { 
    this->colorCode = colorCode; 
} 
int PaintedHouse::getColorCode() { return this->colorCode; } 

OccupiedHouse::OccupiedHouse(int nWindows, int nPeople) : House(nWindows) { 
    this->nPeople = nPeople; 
} 
int OccupiedHouse::getNumberOfPeople() { return this->nPeople; } 

PaintedOccupiedHouse::PaintedOccupiedHouse(int nWindows, int colorCode, int nPeople) 
      : PaintedHouse(nWindows, colorCode), OccupiedHouse(nWindows, nPeople) {} 

GCC回报:

test.cpp: In constructor ‘PaintedOccupiedHouse::PaintedOccupiedHouse(int, int, int)’: 
test.cpp:18:72: error: no matching function for call to ‘House::House()’ 
    : PaintedHouse(nWindows, colorCode), OccupiedHouse(nWindows, nPeople) {} 
                     ^
test.cpp:18:72: note: candidates are: 
test.cpp:4:1: note: House::House(int) 
House::House(int nWindows) { this->nWindows = nWindows; } 
^ 
test.cpp:4:1: note: candidate expects 1 argument, 0 provided 
In file included from test.cpp:2:0: 
test.hpp:2:7: note: constexpr House::House(const House&) 
class House { 
    ^
test.hpp:2:7: note: candidate expects 1 argument, 0 provided 
test.hpp:2:7: note: constexpr House::House(House&&) 
test.hpp:2:7: note: candidate expects 1 argument, 0 provided 

你能告诉我我做错了什么吗?一般概念是否正确?

+0

如果这是为了娱乐目的OK。但我强烈建议由于各种原因避免这种继承方案。 – 101010

+0

在我看来,你的教授希望你探索虚拟基类问题 - 给出的名字非常暗示你画的那种钻石。 – Elemental

+0

@Elemental我没有虚拟基础类的经验...我所有的尝试使用它们编译失败:( –

回答

2

通过

PaintedOccupiedHouse::PaintedOccupiedHouse(int nWindows, int colorCode, int nPeople) 
      : House(nWindows), PaintedHouse(nWindows, colorCode), OccupiedHouse(nWindows, nPeople) {} 

更换

PaintedOccupiedHouse::PaintedOccupiedHouse(int nWindows, int colorCode, int nPeople) 
      : PaintedHouse(nWindows, colorCode), OccupiedHouse(nWindows, nPeople) {} 

当你有虚拟继承,只有一个virtual基类的实例。它必须在构造的最派生类的构造函数中进行初始化。

+0

太棒了,真棒,谢谢! –

1

我建议将PaintingOccupied的东西分成不同的类。 因此,你可以有:

Painted House Occupied 
    |   |  | 
    +---------+--------+ 
      | 
    Painted_Occupied_House 

不想建立可怕的菱形继承。看看你是否可以重构来缓解这个问题。

钻石界面带来了注入更多缺陷的可能性。

+0

来自JAVA背景,我想同意你的看法(尽管每个JAVA开发人员显然不喜欢多个遗产)。然而,类名(及其隐含的特征)是固定的,所以我不能重构任何东西。无论如何,谢谢你的建议! –