2015-01-12 2 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) {} 

ССАГПЗ возвращается:

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

Если это для целей досуга ОК. Но я настоятельно рекомендую избегать таких схем наследования по разным причинам. – 101010

+0

Мне кажется, ваш профессор хотел, чтобы вы изучали проблемы с виртуальным базовым классом - эти имена очень наводят на мысль о том, какой алмаз вы нарисовали. – Elemental

+0

@ Elemental У меня нет опыта работы с виртуальными базовыми классами ... Все мои попытки скомпилировать его с помощью неудачных :( –

ответ

2

Заменить

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

по

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

Если у вас есть виртуального наследования, есть только один экземпляр virtual базового класса. Он должен быть инициализирован в конструкторе построенного самого производного класса.

+0

Отлично, потрясающе, спасибо! –

1

Предлагаю разделить Painting и Occupied материалы на отдельные классы. Таким образом, вы могли бы:

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

Предпочитают не настроить Страшный алмазное наследство. Посмотрите, можете ли вы реорганизовать, чтобы устранить проблему.

Интерфейс с бриллиантом открывает возможность впрыскивания большего количества дефектов.

+0

Исходя из фона JAVA, я хотел бы согласиться с вами (хотя каждый разработчик JAVA явно ненавидит несколько наследование). Однако имена классов (и их подразумеваемые функции) исправлены, поэтому я не могу реорганизовать что-либо. Спасибо за ваше предложение, во всяком случае! –