簡體   English   中英

c ++中的循環繼承

[英]Circular Inheritance in c++

我有三個課程,我想在另一個里面使用它們:

class Object
{
public:
    Object();
    ~Object();


protected:

   int x;
   int y;
private:
  Line l;
  Circle c;
}; 

class Line : public Object
{
public:
    Line ()
        {
           x = x+y;
         }
    ~Line ();


private:
}; 

class Circle : public Object
{
public:
    Circle()
        {
           x = x/y;
         }
    ~Circle();


private:
}; 

所以這里的問題是我在編譯時遇到錯誤,該錯誤表示基本未定義,我嘗試使用#define#ifdefine ,但它不起作用。

理想情況下,我想要做的是在main中調用一個對象,並在那里設置要使用的所有其他變量,同時該對象可以是不同的,這樣它可以是一個LineCircle

你不可以做這個。 編譯器不可能這樣做。

相反,你必須有指向對象的指針,而不是它們的直接實例。

然后這樣做稱為“前進”類的聲明:

class Circle;
class Line;
class Object
{
    Line* line;
    Circle* circle;
}

當然,使用智能指針而不是原始指針會更好。

考慮一下:

  1. 每個Object包含Line ;
  2. 每一Line都是一個Object ;
  3. 因此,每個Object包含一個Object ;
  4. 當然, Object包含一個Object ;
  5. 其中包含一個Object ...等等,直到你累了。

這是嘗試建立無限遞歸的數據結構 ,您可能會看到為什么不允許它。

相反,使用前向聲明和(智能)指針( unique_ptr<>似乎是這里的最佳選擇)來打破相互依賴並允許終止遞歸結構(指針可以為null):

#include <memory>

// Forward declarations
class Line;    
class Circle;

class Object
{
public:
    Object();
    ~Object();
protected:
   int x;
   int y;
private:
  std::unique_ptr<Line> l;
  std::unique_ptr<Circle> c;
};

class Line : public Object
{
public:
    Line ()
        {
           x = x+y;
         }
    ~Line ();
};

class Circle : public Object
{
public:
    Circle()
        {
           x = x/y;
         }
    ~Circle();
};

我的猜測是你希望任何對象都是一個原始的圖形對象,如一條線或一個圓,或一個復合對象,即。 包含其他幾個的對象。

你幾乎就在那里:你應該做的是:

  • 從Object中刪除Object子類實例(請參閱其他答案,原因是這是設計錯誤),

  • 創建繼承Object的第四個類:

     class Compound : public Object { public: Compound(){ } private: Line line; Circle circle; }; 

現在,如果您想以通用方式操作對象列表,那很容易。 您所需要的只是在Object上定義ad-hoc虛擬方法,並在子類中覆蓋它們(例如draw方法)。

有關概念的更多解釋,請參閱本教程中的多態性。

你不能做你剛剛描述的事情。 基類不能包含從中派生的類。 類派生時,它包含基類的所有組件。 因此,在您的示例中,Object包含一個Line和一個Circle。 圓包含包含圓和直線的對象 - 你可以看到我們可以像1/3中的3的數一樣...

您可以有一個引用或指向Line或Circel類對象的指針,例如

class Line;
class Circle

你需要在Object類之前的上面的行 - 它告訴編譯器“有一個類Line和一個類Circle。我將會看到它們實際包含的內容......”

class Object
{
public:
    Object();
    ~Object();


protected:

   int x;
   int y;
private:
  Line* l;
  Circle* c;
}; 

為了使成員變量具有給定類型(如“ Circle c ”),類定義必須已經出現在翻譯單元中。 所以,在這種情況下,你所要求的是不可能的。

但是,指向對象的指針只需要編譯器知道符號(例如“Circle”)表示一個類。 您可以通過前向聲明來完成此操作。 所以一個選擇是

class Circle;
class Line;

class Object {
public:
    ...
    Circle *c;
    Line *l;
}

class Line: public Object { ... }

class Circle: public Object { ... }

在您的代碼中, Object對象包含一個Circle子對象(數據成員),該子對象又包含一個Object子對象(基類子對象),...

產生無限大小 ,這是相當不好的。

但是,解決方案非常簡單:不要從Object派生這些類。

暫無
暫無

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

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