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

构造函数体赋值和初始化列表

在C++中,对象的初始化可以通过两种方式完成:构造函数体内的赋值和使用成员初始化列表。这两种方式有本质区别,理解它们的差异对编写高效、正确的C++代码至关重要。

 

一、基本概念对比

 

1. 构造函数体赋值

 

class MyClass

{

    int a;

    std::string b;

public:

    MyClass(int x, const std::string& y)

    {

        a = x; // 赋值操作

        b = y; // 赋值操作

    }

};

 

 

2. 初始化列表

 

class MyClass

{

    int a;

    std::string b;

public:

    MyClass(int x, const std::string& y) 

        : a(x), // 初始化

          b(y) // 初始化 

    {

        // 构造函数体

    }

};

 

 

二、关键区别

 

1. 执行时机不同

 

- 初始化列表:在对象构造阶段完成初始化

- 构造函数体赋值:对象已构造完成后进行赋值

 

2. 性能差异

 

- 对于类类型成员:

- 初始化列表直接调用拷贝构造函数

- 构造函数体赋值会先调用默认构造函数,再调用赋值运算符

 

3. 必须使用初始化列表的情况

 

以下情况必须使用初始化列表:

 

- const成员变量

- 引用类型成员

- 没有默认构造函数的类类型成员

- 基类初始化

 

三、初始化列表详解

 

1. 语法规则

 

ClassName::ClassName(params) 

    : member1(value1), 

      member2(value2),

      ...

{

    // 构造函数体

}

 

 

2. 初始化顺序

 

初始化顺序由成员在类中的声明顺序决定,与初始化列表中的顺序无关。

 

class Example

{

    int a;

    int b;

public:

    Example(int x) : b(x), a(b) {} // 危险!a先初始化,此时b未初始化

};

 

 

3. 基类和成员混合初始化

 

class Derived : public Base

{

    int x;

    std::string s;

public:

    Derived(int a, const std::string& str)

        : Base(a), // 基类初始化

          x(a), // 成员变量初始化

          s(str) // 成员变量初始化

    {

        // 构造函数体

    }

};

 

 

四、构造函数体赋值的适用场景

 

虽然初始化列表通常是更好的选择,但在以下情况可能需要在构造函数体内赋值:

 

1. 需要复杂逻辑初始化

 

class ComplexInit

{

    int value;

public:

    ComplexInit(bool flag)

      {

        if(flag)

       {

            value = computeValue1();

        }

       else

       {

            value = computeValue2();

        }

    }

};

 

 

2. 需要异常处理

 

class FileHandler

{

    FILE* file;

public:

    FileHandler(const char* filename)

   {

        file = fopen(filename, "r");

        if(!file)

       {

            throw std::runtime_error("File open failed");

        }

    }

};

 

 

五、性能优化建议

 

1. 优先使用初始化列表:特别是对于类类型成员

2. 简单类型成员:内置类型(int, float等)两种方式性能差异不大

3. 避免重复初始化:使用初始化列表避免不必要的默认构造+赋值

4. 保持声明顺序与初始化顺序一致:提高代码可读性,避免潜在问题

 

六、综合示例

 

class Student

{

    const int id; // const成员

    std::string name; // 类类型成员

    int& ageRef; // 引用成员

    double scores[3]; // 数组

public:

    Student(int sid, const std::string& n, int& age)

        : id(sid), // const成员必须初始化

          name(n), // 直接初始化,效率高

          ageRef(age), // 引用必须初始化

          scores{0,0,0} // 数组初始化

    {

        // 构造函数体内可进行复杂操作

        if(name.empty())

       {

            name = "Unknown";

        }

    }

};

求关注!!!! 

相关文章:

  • 面试题:在1亿个数据中取前10个最大的数据(Java实现)
  • 【数据结构】Map与Set结构详解
  • 开源交易所源码,交易所开发
  • 时序数据库IoTDB构建的能源电力解决方案
  • 无人设备遥控之调度自动化技术篇
  • 从岗位依附到能力生态:AI革命下“什么叫就业”的重构与价值
  • Python3(8) 字符串
  • 使用HYPRE库并行装配IJ稀疏矩阵指南: 矩阵预分配和重复利用
  • 数据集-目标检测系列- F35 战斗机 检测数据集 F35 plane >> DataBall
  • 数据分析之技术干货业务价值​​ powerquery 分组排序后取TOP
  • Code Splitting 分包策略
  • 【网络原理】从零开始深入理解TCP的各项特性和机制.(一)
  • 立錡科技优化 HDD、LPDDR、SoC 供电的高性能降压转换器
  • Python实现技能记录系统
  • 【华为OD机试真题】428、连续字母长度 | 机试真题+思路参考+代码解析(E卷)(C++)
  • Browser-Use WebUI:让AI自动使用浏览器帮你查询信息执行任务
  • StableDiffusionPipeline原理解读——引导尺度是如何调整噪声残差的
  • 【C语言经典算法实战】:从“移动距离”问题看矩阵坐标计算
  • 审计效率升级!快速匹配Excel报表项目对应的Word附注序号
  • Ubuntu / WSL 安装pipx
  • 蚂蚁集团将向全体股东分红
  • 外交部:美国是国际军控与防扩散体系的最大破坏者
  • 无视规范开“远端”、企业云端被窃密,国安部:莫让运维成运“危”
  • 3岁男童疑遭父亲虐待,杭州警方:在异地发生,嫌疑人已被抓
  • 下周起上海浦东将投放5000万元消费券,预计分五周发放
  • 上海楼市明显复苏:一季度房地产开发投资增长5.1%,土地市场重燃战火