[英]object orientation, inheritance, and composition in c++
共有4個類別:A,B,C和D。類別A是“ HAS A” B,類別C是“ HAS A” D。碰巧是C“ IS A” A和D“ IS A” B。在C ++中為這些關系建模的最佳方法是什么?
A具有的B與C具有相同的D。
示例:建築物有入口,而房屋有門。 房子是建築物,門是入口。
class B {
};
class A {
B b; // A "has a" B
};
class C : public A { // C "is a" A
D d; // C "has a" D
};
class D : public B { // D "is a" B
};
我認為您的設計存在缺陷。 如果我理解正確,則希望限制基類成員變量的類型:
struct Entrance {};
struct Door : public Entrance {};
struct Building
{
Entrance * entrance; // raw pointer just for the sake of clarity
};
struct House : public Building
{
// Building::entrance must always be a door
};
您可以使用訪問器(getter / setter) entrance
並檢查類型,如果入口不是門,則引發異常,但這會破壞Liskov替換原理 :您將無法像操縱House
那樣操作House
在Building
:
struct Drawbridge : public Entrance {};
House house;
Drawbridge bridge;
Building & building = house;
building.setEntrance(bridge);
// Oups, I'm trying to install a drawbridge on my house!
一些庫執行這種限制(例如,當人們嘗試修改其內容時, ReadOnlyCollection<T>
會引發異常),但是在我看來,這不是一個干凈的設計。 如果collection的界面指出我可以向collection中添加元素,則只讀collection 不是 collection(因為它不支持添加元素)。
在這里可以應用相同的推理: House
不是 Building
因為它不能包含所有類型的Entrance
。
建築物有入口,而房屋則有門。 房子是建築物,門是入口。
struct Entrance {};
struct Door : Entrance {};
struct Building {
virtual Entrance& getEntrance() = 0;
};
struct House : Building {
virtual Entrance& getEntrance() {
return entrance;
}
private:
Door entrance;
};
typedef Building A;
typedef Entrance B;
typedef House C;
typedef Door D;
這是使用多態性的最近似方法。 請特別注意, Building
無法實例化,因為它是“抽象”的。
否則,您不能讓A
具有B
和 C
具有D
, 並且 B
和D
都是同一對象。
如果您很想嘗試讓基准保持引用 ,請避免使用它:
struct Entrance {};
struct Door : Entrance {};
struct Building {
Building(Entrance& e) : e(e) {}
Entrance& e;
};
struct House : Building {
House() : Building(e) {}
Door e;
};
typedef Building A;
typedef Entrance B;
typedef House C;
typedef Door D;
由於House
的Building
構造函數是在創建Door
之前被調用的, 因此這充其量是有問題的 (最壞的情況下是未定義的。我必須查找它)。
盧克說得對,但是這種建模有缺陷。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.