[英]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.