C++ 初始化列表和构造函数成员属性的区别

说明,除了以下四种情况,编译器强制要求采用初始化列表:

1 包含常量成员,必须初始化列表进行初始化
2 包含引用成员,必须初始化列表进行初始化
3 包含成员类对象,并且有显示构造函数,必须要初始化列表进行初始化
4 继承于基类,并且基类有显示构造函数,必须要初始化列表进行初始化

实例:

#include<iostream>

using namespace std;

class Word{
public:
    Word(int _id, const int _age, string _name):id(_id),age(_age),name(_name){}

    //常量成员和引用必须初始化列表进行初始化

    // Word(int _id, const int _age)
    // {
    //     id = _id;
    //     age = _age;    // 常量成员只能初始化  不能赋值
    //     name = _name;  // 引用成员只能初始化  不能赋值
    // }
private:
    int id;
    const int age;
    string &name;
};

class Article{
public:
    // 包含成员 类对象并且有显示构造函数,必须要初始化列表进行初始化
    Article(int _size):w(0,0," "),size(_size){}

    //下面错误
    // Article(int _size)
    // {
    //     w(0,0,0);          
    //     size = _size;
    // }
private:
    Word w;
    int size;
};

class Article2:public Word{
public:
    // 继承基类,并且基类有显示构造函数,必须要初始化列表进行初始化
    Article2(int _size):Word(0,0," "),size(_size){}  
private:
    int size;
};

但是需要说明,函数体内进行类成员初始化,效率并不高:

class Word{
private:
    string _name;
    int _age;
public:
    Word(string name, int age)
    {
        _name = name;
        _age = age;
    }
};

--->
// 编译器实现上面的初始化string成员的过程,
// 1 调用string的默认构造函数初始化_name
// 2 构建一个临时string对象temp
// 3 调用string的赋值运算符=
// 4 调用临时对象的析构函数

  Word(string name, int age)
    {
        _name.string::string();            <- 1
  
  	string temp = string(name);        <- 2
  
  	_name.string::operator=(temp);     <- 3
  
  	temp.string::~string();            <- 4

  	_age = age;
    }
posted @ 2021-08-26 21:43  Arrkwin  阅读(128)  评论(0编辑  收藏  举报