簡體   English   中英

C ++中的面向對象,繼承和組合

[英]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那樣操作HouseBuilding

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並且 BD都是同一對象。


如果您很想嘗試讓基准保持引用 ,請避免使用它:

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;

由於HouseBuilding構造函數是在創建Door之前被調用的, 因此這充其量是有問題的 (最壞的情況下未定義的。我必須查找它)。


盧克說得對,但是這種建模有缺陷。

C擴展了A,D擴展了B。A在其定義中持有B對象,C持有D對象。 [有-有] [有-有]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM