问题描述
为什么我不允许使用以下语法在类的构造函数的主体中调用成员对象/不同类的构造函数?
class Circle {
double radius;
public:
circle(double r):radius(r){}
double area(){return radius * radius * 3.14159265;}
};
class Cylinder {
Circle base;
double height;
public:
油缸(双r,双h){
base(r);
height = h;
}
double volume(){return base.area()* height;}
};
顺便说一下,我知道我可以调用 Circle :: Circle 通过使用成员初始化列表 Cylinder(double r,double h):base(r ),height(r){} 但是仍然有什么问题,前面的方法,编译器生成这个错误?
问题是,当C ++开始执行构造函数代码时,所有的成员变量必须已经被构造了(例如,如果你在构建之前调用 Circle 的方法? )。
如果立即构造是一个问题,那么一个可能的解决方案是添加一个默认构造函数
您可以想象原生类型如 int 或 double 有一个默认的构造函数,这就是为什么你可以初始化它们以后(注意,然而对于语言的许多丑陋的奇怪之一的默认构造函数 int 或 double 实际上不会执行任何操作在此情况下
不能使用 base(r) 在正文中,因为它不是一个有效的语句...跟在一个带有开始括号的名称仅用于函数调用,在声明中初始化或在构造函数成员初始化列表中的成员初始化。 / p>
如果您使用默认构造函数提供 Circle ,则可以执行
油缸(double r,double h){
base = Circle(r);
height = h;
}
请注意,构建非工作对象以修复它们的方法不是C ++的最佳方法。语言喜欢这样的想法,如果一个对象被构造,那么它是可用的,偏离这是只有在必要的时候才考虑(C ++ 11漂移了一点从这个原始的路径与移动构造函数...但这是另一个故事) p>
Why am I not allowed to use the following syntax to call a constructor of a member object/different class in the body of the constructor of a class?
class Circle { double radius; public: Circle(double r) : radius(r) { } double area() {return radius*radius*3.14159265;} }; class Cylinder { Circle base; double height; public: Cylinder(double r, double h) { base(r); height = h; } double volume() {return base.area() * height;} };
By the way I know I can call Circle::Circle(double) via Cylinder(double,double) using member initialization list like Cylinder(double r,double h) : base(r), height(r) {} but still what's wrong with the former method that the compiler is generating this error?
The problem is that when C++ begins the execution of the constructor code all the member variables must have been already constructed (what if you for example call a method of Circle before constructing it?).
If immediate construction is a problem then a possible solution is to add to your member a default constructor and the using assignment in the body of the constructor of the containing class.
You can imagine that native types like int or double do have a default constructor, that's why you can initialize them later (note however that for one of the many ugly quirks of the language the default constructor for an int or a double doesn't actually do anything in this case and you're not allowed to do anything with such a member except assigning it a value - for example reading it is not allowed).
You cannot use base(r) in the body because that's not a valid statement... following a name with an opening parenthesis is only used for function call, for initialization in a declaration or for member initialization in the constructor member initialization list.
If you provide Circle with a default constructor then you can do
Cylinder(double r, double h) { base = Circle(r); height = h; }
Note however that the approach of constructing non-working objects to fix them later is not the best approach for C++. The language likes the idea that if an object is constructed then it's usable and deviations from this are considered only when necessary (C++11 drifted away a bit from this original path with move constructor... but that's another story).
这篇关于调用构造函数体中的成员对象的构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!