[英]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
中調用一個對象,並在那里設置要使用的所有其他變量,同時該對象可以是不同的,這樣它可以是一個Line
或Circle
。
你不可以做這個。 編譯器不可能這樣做。
相反,你必須有指向對象的指針,而不是它們的直接實例。
然后這樣做稱為“前進”類的聲明:
class Circle;
class Line;
class Object
{
Line* line;
Circle* circle;
}
當然,使用智能指針而不是原始指針會更好。
考慮一下:
Object
包含Line
; Line
都是一個Object
; Object
包含一個Object
; Object
包含一個Object
; 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.