C++ 类成员初始化方式详解:赋值初始化 vs 初始化列表

1. 类成员初始化方式

在 C++ 中,类成员的初始化有两种主要方式:

  1. 赋值初始化:在构造函数体内部对成员进行赋值。
  2. 初始化列表:在构造函数定义时,在冒号的后面使用初始化列表进行初始化。
赋值初始化

赋值初始化是在构造函数体内对成员进行赋值。这意味着成员变量在构造函数体内被赋值之前,已经被默认构造了。

初始化列表

初始化列表是在构造函数冒号后对成员进行初始化,这是在成员被分配内存的同时进行的初始化操作。这样避免了成员变量先被默认构造然后再赋值的过程。

#include <iostream>

class MyClass {
public:
    int x;
    int y;

    // 赋值初始化
    MyClass(int a, int b) {
        x = a;  // 赋值初始化
        y = b;  // 赋值初始化
    }

    // 初始化列表
    MyClass(int a, int b) : x(a), y(b) {}  // 初始化列表
};

2. 构造函数的执行顺序

构造函数的执行顺序对于派生类来说是比较规则的。派生类对象的构造顺序遵循以下步骤:

  1. 虚拟基类的构造函数(如果有多个虚拟基类,则按继承关系中声明的顺序执行它们的构造函数)。
  2. 普通基类的构造函数(按继承顺序执行)。
  3. 类类型成员对象的构造函数(按声明顺序执行)。
  4. 派生类的构造函数(最后执行)。

通过以下例子说明:

#include <iostream>

class BaseA {
public:
    BaseA() { std::cout << "BaseA Constructor\n"; }
};

class BaseB {
public:
    BaseB() { std::cout << "BaseB Constructor\n"; }
};

class Member {
public:
    Member() { std::cout << "Member Constructor\n"; }
};

class Derived : public BaseA, public BaseB {
public:
    Member m;

    Derived() { std::cout << "Derived Constructor\n"; }
};

int main() {
    Derived d;
    return 0;
}

以上程序的输出将是:

BaseA Constructor
BaseB Constructor
Member Constructor
Derived Constructor

3. 为什么使用成员初始化列表会更快

使用成员初始化列表比在构造函数体内部赋值会更高效的原因如下:

  • 避免了不必要的默认构造和赋值:在构造函数体内部赋值,成员变量先默认构造,然后再赋值。而通过初始化列表,成员在分配内存时就直接初始化,可以避免默认构造和随后的赋值操作。

  • 减少临时对象的构造:通过初始化列表,构造函数直接初始化成员,而不需要先产生临时对象然后再赋值给成员。

让我们再举一个成员是对象的例子:

#include <iostream>
#include <string>

class MyObject {
public:
    std::string value;

    // 使用赋值初始化
    MyObject() {
        value = "Hello, World!";
        std::cout << "MyObject assignment constructor: " << value << std::endl;
    }

    // 使用初始化列表
    MyObject(const std::string& s) : value(s) {
        std::cout << "MyObject initializer list constructor: " << value << std::endl;
    }
};

int main() {
    MyObject obj1;
    MyObject obj2("Hello, C++!");

    return 0;
}

运行结果:

MyObject assignment constructor: Hello, World!
MyObject initializer list constructor: Hello, C++!

为了提高效率,尽量使用成员初始化列表来初始化类成员。

小结

以上总结了类成员初始化的两种方式、构造函数执行顺序及其原因,并通过代码举例说明。希望这些解释和例子能帮助你更好地理解和应用这些 C++ 特性。

  • 12
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
unordered_map的初始化可以通过不同的方式进行。一种是使用默认构造函数创建一个空的unordered_map容器,如引用中的代码所示: ``` unordered_map<string, string> umap; ``` 这个语句创建了一个空的unordered_map容器,键的型为string,值的型也为string。你还可以在创建时直接添加键值对,如引用中的代码所示: ``` unordered_map<string, string> umap = {{"Python教程", "http://c.biancheng.net/python/"}, {"Java教程", "http://c.biancheng.net/java/"}, {"Linux教程", "http://c.biancheng.net/linux/"}}; ``` 这个语句创建了一个包含三个键值对的unordered_map容器,分别是{"Python教程", "http://c.biancheng.net/python/"}, {"Java教程", "http://c.biancheng.net/java/"}, {"Linux教程", "http://c.biancheng.net/linux/"}。你还可以使用emplace或insert函数添加键值对,如引用中的代码所示: ``` unordered_map<string, string> umap; umap.emplace("Python教程", "http://c.biancheng.net/python/"); umap.emplace("Java教程", "http://c.biancheng.net/java/"); umap.emplace("Linux教程", "http://c.biancheng.net/linux/"); ``` 这个代码使用emplace函数将三个键值对添加到unordered_map容器中。最后,你还可以使用unordered_map的赋值操作符或拷贝构造函数来初始化一个unordered_map容器,如引用中的代码所示: ``` unordered_map<string, string> umap1 = umap; // 使用拷贝构造函数 unordered_map<string, string> umap2; umap2 = umap; // 使用赋值操作符 ``` 这个代码将一个unordered_map容器umap赋值给另外两个unordered_map容器umap1和umap2。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [C++ STL unordered_map容器用法详解](https://blog.csdn.net/u010038790/article/details/118737155)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [字符串快速映射为整数](https://download.csdn.net/download/aZhuang/13026945)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值