C++默认构造函数

C++ primer中的三个地方讲解了默认构造函数:

P44变量初始化规则

P227函数(构造函数)

P388类(构造函数初始化式)


一, 变量初始化规则(P44和P227)

1,对于类类型的成员,调用该成员所属类自身的默认构造函数实现初始化。

2,内置类型成员的初值依赖于对象定义的位置,如果对象在全局作用域中定义(既不在任何函数中)或定义为静态局部对象,则这些成员将被初始化为0;

3,如果对象在局部作用域中定义,则这些成员没有初始化


二,初始化列表

由P49和P50可知:const和引用类型的成员,不能对它们赋值,所以必须在定义时初始化!

所以,对于const对象或引用类型的对象,在开始执行构造函数的函数体之前,要完成初始化!(P389)

初始化 const 引用类型数据成员的唯一机会是在构造函数初始化列表中

同时,由于没有默认构造函数的类类型的成员,编译器尝试使用默认构造函数将会失败,所以也必须在初始化列表中初始化!


二, 默认构造函数的定义

在P225定义了默认构造函数:没有形参。

再看看百度百科的定义:默认构造函数(default constructor)就是在没有显式提供初始化式时调用的构造函数。它由不带参数的构造函数,或者为所有的形参提供默认实参的构造函数定义。如果定义某个类的变量(对象)时没有提供初始化式就会使用默认构造函数。

在P227中说:如果没有为一个类显示定义任何构造函数,编译器将自动为这个类生成默认构造函数,通常称为合成的默认构造函数,它一般用于仅包含类类型成员的类!它不会自动初始化内置类型或复合类型的成员。所以,对于含有内置类型或复合类型成员的类,通常应该定义他们自己的默认构造函数初始化这些成员。


问题:是不是所有的类都有默认构造函数?答案是否定的。

1, 虽然编译器会为类自动生成一个合成的默认构造函数,但是它仅对于包含类类型成员的类。所以对于只含有内置类型或复合类型成员的类,如果不自定义他们的构造函数,编译器不会自动为其生成一个合成的默认构造函数的!

class Sales_item{
public:
        ......
        //<span style="color:#ff0000;">Sales_item():units_sold(0), revenue(0.0){}</span>
private:
        //<span style="color:#ff0000;">std::string isbn;//去掉它,编译器就不会为本类自动生成默认构造函数!</span>
        unsigned units_sold;
        double revenue;
};

2, 当然,如果类显示定义了默认构造函数,但是没有为其类类型的成员在初始化列表中显示初始化,那么会调用该成员所属类自身的默认构造函数实现初始化!这部分工作也是由编译器自动完成的!

<span style="color:#330033;">class Sales_item{
public:
        ......
        Sales_item():</span><span style="color:#ff0000;">units_sold(0), revenue(0.0){}//如果为isbn成员也在这里显示初始化,那么编译器将忽略string的默认构造函数~</span><span style="color:#330033;">
private:
        </span><span style="color:#ff0000;">std::string isbn;//虽然显示定义的默认构造函数,但是它的初始化是由编译器完成的!</span><span style="color:#330033;">
        unsigned units_sold;
        double revenue;
};</span>
3, 如果显示定义带参数的构造函数,那么编译器通常也会自动生成一个合成的默认构造函数,此时,类有两个构造函数!同时编译器也完成上面第2点的工作。

class Sales_item{
public:
        ......
        <span style="color:#ff0000;">Sales_item(double rev)</span>:units_sold(0), revenue(rev){}
private:
        std::string isbn;
        unsigned units_sold;
        double revenue;
};



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。