我正在尝试了解类的默认构造函数工作,但无法弄清楚这种情况:
案例1:
class A
{
public:
int m;
string s;
};
然后我创建此类的对象:
a) A a; // Result: compiler initializing m with garbage value
b) A a = A(); // Result : compiler initializing m with garbage value
案例 2:现在我从我的类中删除了字符串s
:
class A
{
public:
int m;
};
a) A a; // Result: when try to access m I get run time error
b) A a = A(); //Result: m is initialized to zero
问题 1)为什么案例 1 和案例 2 存在差异?
Q2) 如果我在这两种情况下都为我的类提供默认构造函数,那么 a) 和 b) 将是相同的?
因为在这两种情况下,整数都是未初始化的。 这意味着它的值是未定义的。 它可以是零,也可以是整数可以容纳的任何其他值。
如果要在默认构造函数中将其初始化为零,可以这样做:
class A
{
public:
A::A();
int m;
};
A::A()
: m( 0 )
{}
请注意,您不必为 string
提供显式构造函数,因为它是一个类,并且具有自己的默认构造函数。
情况 1:类 A
是非 POD。
情况 2:类 A
是一个 POD。
a) A a; //This is default initialization
b) A a = A(); // This is value initialization
情况 '1':编译器生成的默认构造函数将m
初始化为某个垃圾值。
情况 '2':m
初始化为零,因为A
是一个 POD。
在任何情况下,您都不应该崩溃。如果你这样做,你可能正在使用一个损坏的编译器。
有关默认初始化和值初始化的更多详细信息,请参阅此链接。
情况 1 和情况 2 之间class A
的唯一区别是,在情况 1 中,编译器将系统化一个非平凡的默认构造函数,因为class A
中的s
是非基元类型。但是,在这两种情况下,都不会初始化m
。