问题描述
来自JavaScript和Python,我试图了解C ++类构造函数的细微差别和目的。
在下面的示例中,为什么允许在没有构造函数的情况下初始化属性?
class MyClass {
public:
int a = 1;
int b = 2;
};
默认构造函数是否包含上述定义/初始化?与以下两个示例有什么区别?:
1。
class MyClass {
public:
int a;
int b;
MyClass(){
a = 1;
b = 2;
}
};
- JavaScript / Python样式(这可能吗?)
class MyClass {
public:
MyClass(){
// Some kind of variable declaration and deFinition like:
// this.a = 1;
// this.b = 2;
}
};
对我来说,可以选择不带构造函数进行初始化的选项听起来像是过分杀人,而且令人困惑。在Python和JavaScript中,通常都从构造函数中声明并初始化所有变量,并且仅从那里开始。
这里的最佳做法是什么?
解决方法
在下面的示例中,为什么允许在没有构造函数的情况下初始化属性?
因为C ++ 11特别添加了该功能。参见Member initialization。
默认构造函数是否包含上述定义/初始化?
是的。这段代码:
stdin
大致(不完全)等效于以下代码:
sys.__stdout__ = sys.stdout
实际上可以同时使用两种初始化形式,例如:
class MyClass {
public:
int a = 1;
int b = 2;
};
可以用以下两种方法之一初始化非静态数据成员:
在构造函数的成员初始化器列表中。
通过默认的成员初始化程序,该初始化程序是成员声明中包含的大括号或等于初始值设定项,如果从构造函数的成员初始化程序列表中省略了该成员,则使用该默认值。
如果成员具有默认成员初始化程序,并且该成员也出现在构造函数的成员初始化列表中,则该构造函数将忽略默认成员初始化程序。
default constructor的member initialization list中未指定class MyClass {
public:
int a;
int b;
MyClass() : a(1),b(2) {}
};
成员,因此当默认构造class MyClass {
public:
int a = 1;
int b = 2;
MyClass() = default;
MyClass(int a) : a(a) {}
};
对象时,它将使用其默认值1初始化。
a
成员在converting constructor的member initialization list中进行了显式初始化,因此其默认值MyClass
将被忽略,而是由调用者初始化用输入值构造a
对象时提供的值。
在任何一个构造函数的member initialization list中均未指定1
成员,因此将始终使用其默认值2对其进行初始化。
与以下两个示例有何区别?
第一个示例是在C ++ 11之前必须要做的(如果您不使用构造函数的member initialization list,如上所示)。
第二个示例在C ++中不合法。您不能动态地声明成员,当然也不能从构造函数内部。必须在类声明本身中对其进行静态声明。