C++构造函数的初始化列表

Posted 流浪孤儿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++构造函数的初始化列表相关的知识,希望对你有一定的参考价值。

目录

先谈赋值

 多次赋值

定义

初始化

初始化列表

 不能对同一个变量多次进行初始化

 注意

 不使用初始化列表初始化A类对象

 自定义类型成员有相应的默认构造函数时

 初始化列表中的初始化顺序

 调试证明:

 类中的static成员进行初始化

 概念

 特性

C++11初始化新玩法

先谈赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

 

 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称作为类对象成员的初始化,构造函数体中的语句只能将其称作为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。(初始化是在变量定义的时候赋初值,赋值是在变量定义好后给予新值)

 多次赋值

定义

 初始化

 

 初始化列表

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。

初始化列表是对象的成员变量进行定义的地方(初始化是发生在定义的时候的,因此初始化列表可以初始化变量,而在函数体中只能进行赋值)

 

 不能对同一个变量多次进行初始化

 注意

1、每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

2、类中包含以下成员,必须放在初始化列表位置进行初始化:

        引用成员变量:引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面

        const成员变量:该变量初始化之后就不能再赋值了,不进行初始化也不能赋值给它,赋值相当于修改值

        自定义类型成员(该类没有相应的默认构造函数,但总会至少有一个默认构造函数,无参的或有参的):没有相应的默认构造函数的类类型,那么使用初始化列表就可以去调用其另外一个存在但不是相应的默认构造函数的初始列表进行初始化

 3、拷贝构造函数里也可以放初始化列表

 4、即使你没有将某个成员变量放进初始化列表,编译器也会在执行初始化列表的时候定义该成员变量(此时因为没有初始值因此可能仅仅是定义没有进行初始化)

 

 不使用初始化列表初始化A类对象

 说明:定义一个A类对象会调用A类的构造函数,当不使用初始化列表定义_aobj对象,那么编译器会调用无参构造函数初始化(注意编译器在这种情况不会去调用A(int a):_a(a){}有参构造函数,因为没有传参)

 自定义类型成员有相应的默认构造函数时

 _aobj并没有使用初始化列表,编译器调用A(int a=0) :_a(a){}来初始化_aobj对象,因为这个构造函数有缺省值因此不需要传参便可以调用                                                                       总结:尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用该自定义类型的初始化列表初始化。

 初始化列表中的初始化顺序

成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关

 

 调试证明:

调试环境为visual studio 2017

 

 

 

 

 

 类中的static成员进行初始化

 概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰成员函数,称之为静态成员函数静态的成员变量一定要在类外进行初始化

 特性

  1. 静态成员为所有类对象所共享,不属于某个具体的实例
  2. 静态成员变量必须在类外定义,定义时不添加static关键字
  3. 类静态成员即可用类名::静态成员或者对象.静态成员来访问,前提是该成员是public的
  4. 静态成员和类的普通成员一样,也有public、protected、private3种访问级别
  5. 静态成员函数和类的普通成员一样,也有public、protected、private3种访问级别,也可以有返回值
  6. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  7. 静态成员函数不可以调用非静态成员函数
  8. 非静态成员函数可以调用类的静态成员函数

C++11初始化新玩法

 C++11支持非静态成员变量在声明时进行初始化赋值,但是要注意这里不是初始化,这里是给声明的成员变量缺省值

#include <iostream>

using namespace std;

class Date

{

public:

    Date()

       :_year(10)

    {}

    void Print()

    {

       cout << _year << "-" << _month << "-" << _day << endl;

    }

private:

    // C++11才支持

    // 声明时给缺省值(这样就可以实现即使你没给内置类型做处理也能自己初始化了

    int _year = 0;//给了缺省值那么当初始化列表中没有写他们就会默认用缺省值进行初始化

    int _month = 1;

    int _day = 1;

    int* p = (int*)malloc(4);

    static int _n;//不能给静态成员缺省值,静态成员必须在类外定义并初始化

};

int Date::_n = 1;

int main()

{

    Date d1;

    d1.Print();

    return 0;

}

以上是关于C++构造函数的初始化列表的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C++ 列表初始化也会考虑常规构造函数?

构造函数中的 C++ 初始化列表

C++构造函数的初始化列表

C++中数组的构造函数初始化列表

C++:初始化成员变量(无参构造|有参构造|初始化列表)

c++ 初始化列表VS构造函数内赋值初始化成员变量