当前位置: 首页 > article >正文

什么是 C++ 中的初始化列表?它的作用是什么?初始化列表和在构造函数体内赋值有什么区别?

定义

在 C++ 中,初始化列表是一种用于初始化类的数据成员的语法机制。它在构造函数的定义中使用,位于构造函数的参数列表之后,函数体之前,以一个冒号:开始

class MyClass {
private:
    int num;
    double value;
public:
    MyClass(int n, double v) : num(n), value(v) {
    }
};

作用

在对象创建时,对成员变量进行初始化,特别是对于const成员变量、引用成员变量和没有默认构造函数的成员对象,必须使用初始化参数列表进行初始化,只能在构造函数中使用。

初始化的顺序和成员变量的顺序一致,和初始化参数列表的顺序无关

class A {
    int a;
    int b;
    int c;
    const int d;
    int& e;
public:
    A() :a(1), c(2), b(c), d(2), e(a) {
        cout << a << " " << b << " " << c << endl;//打印结果为1,-839928,2。因为是按照成员变量的顺序进行初始化的
    }
    A(int a, int b, int c, int d, int e) :a(a), b(b), c(c), d(d), e(e) {}
};
int main() {
    A a;
}

初始化列表和在构造函数体内赋值有什么区别?

构造函数是给成员变量赋值的

初始化参数列表是给成员变量初始化的

对特殊类型成员

初始化列表:

对于const成员变量,因为const变量在初始化后不能再被赋值,所以必须使用初始化列表来初始化。

class ConstClass {
private:
    const int const_num;
public:
    ConstClass(int n) : const_num(n) {
    }
};

引用类型的成员变量也必须在初始化列表中初始化。引用在定义后不能重新绑定到其他对象,所以需要在初始化时确定其引用的对象

class RefClass {
private:
    int& ref_num;
public:
    RefClass(int& n) : ref_num(n) {
    }
};

构造函数体内赋值:

无法用于初始化const成员和引用成员。因为在构造函数体执行时,const成员已经被默认初始化(不符合要求),引用成员如果没有在初始化列表初始化,在构造函数体中就无法再进行合法的初始化。

性能差异

初始化列表:

对于包含其他类对象作为成员(成员对象)的情况,初始化列表可以更高效地初始化这些成员对象。如果在初始化列表中调用成员对象的构造函数,成员对象的构造函数只会被调用一次,按照正确的顺序初始化。

假设有一个类Container包含一个std::vector成员vec,在初始化列表中初始化vec可以避免不必要的默认构造和重新赋值操作

class Container {
private:
    std::vector<int> vec;
public:
    Container() : vec(10) {  // 直接初始化为包含10个元素的vector
    }
};

构造函数体内赋值:

如果先默认构造成员对象,然后在构造函数体内赋值,可能会导致额外的性能开销。对于一些资源密集型的对象,如动态分配内存的对象,这可能会涉及到多次内存分配和释放操作。例如,如果在构造函数体内给std::vector成员赋值,可能会先默认构造一个空的vector,然后再重新分配内存来存储新的值,这比直接在初始化列表中初始化效率要低。

对于一些需要在构造函数体内进行复杂计算的成员变量,可以先用初始化列表中进行默认初始化,然后再构造函数体内进行赋值。

class Rectangle {
private:
    double length;
    double width;
    double area;
public:
    Rectangle(double l, double w) : length(l), width(w), area(0) {
        // 在构造函数体内进行复杂计算(这里是计算面积)
        area = length * width;
    }
    double getArea() {
        return area;
    }
};

在初始化列表中对length和width进行了初始化,同时对area进行了默认初始化(初始化为 0)。这是因为在进入构造函数体之前,我们还没有计算出area的值,所以先给它一个默认值。


http://www.kler.cn/a/403514.html

相关文章:

  • C语言教程指针笔记整理(二)
  • 第 24 章 -Golang 性能优化
  • 【加入默语老师的私域】C#面试题
  • 智能工厂的设计软件 为了监管控一体化的全能Supervisor 的监督学习 之 序8 进化论及科学的信息技术创新:分布式账本/区块链/智能合约 之2
  • 【Qt】QComboBox设置默认显示为空
  • Springboot + vue 健身房管理系统项目部署
  • 【Lucene】详解倒排表的结构,如何实现词典与文档的映射关系
  • 数据结构概述及线性结构
  • IL-AD
  • 付费会员数量统计错误修复
  • RabbitMQ 高级特性——延迟队列
  • vitess使用:从部署到go客户端连接查询
  • 深入解析PostgreSQL中的PL/pgSQL语法
  • React Native 全栈开发实战班 - 用户界面之手势系统应用
  • Android ConstraintLayout 基础
  • Day03_AJAX原理 (黑马笔记)
  • Python从0到100(七十三):Python OpenCV-OpenCV实现手势虚拟拖拽
  • 2025年软考初级【信息处理技术员】考试大纲
  • SELinux 的端口号权限以及使用 semanage 工具添加权限
  • 《TCP/IP网络编程》学习笔记 | Chapter 12:I/O 复用
  • Ubuntu 22.04 上快速搭建 Samba 文件共享服务器
  • 微信小程序的医院预约挂号系统
  • netcore Kafka
  • 【SQL 实现计算已历完整月份不同日期的场景】
  • JDK安装和Linux常见设置详细版教程
  • springboot第82集:消息队列kafka,kafka-map