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

C++ 6种构造函数简化记忆

对C++构造函数的记忆,不管对于在 C++老兵还是新手,都是一个很头痛的问题。新手困惑于构造函数种类繁多,应用场景各异。老手则困惑于记过则忘,难以长久。今天花点时间,简单做一个汇总,方便新手理解,同时也方便老手记忆。

构造函数(Constructor)是类的特殊成员函数,主要用于控制对象的初始化过程。其名称与类名相同,无返回类型(包括 void)。根据功能和设计场景的不同,C++ 支持多达6种类型的构造函数。

以下是对这6种构造函数类型的压缩简化版本:

1. 默认构造函数(Default Constructor)​

定义​:无参构造函数,或所有参数均有默认值的构造函数。

作用​:当创建对象时未显式提供初始化参数时,编译器自动调用默认构造函数完成对象的初始化。

特点​:

  • 若类中未显式定义任何构造函数,编译器会自动生成一个隐式默认构造函数​(行为为空,仅对内置类型(如 int、指针)不做初始化,对类类型成员调用其默认构造函数)。

  • 若类中显式定义了其他构造函数(如参数化构造函数),编译器不再自动生成隐式默认构造函数​(需手动定义或使用 = default显式保留)。

示例​:

class Sensor {
public:// 隐式默认构造函数(编译器自动生成)// Sensor() = default;  // 显式保留默认构造函数(可选)// 显式定义的默认构造函数(无参)Sensor() : id(0), is_active(false) {}private:int id;bool is_active;
};// 使用场景:创建对象时不传递参数
Sensor s1;  // 调用默认构造函数

2. 参数化构造函数(Parameterized Constructor)​

定义​:带有至少一个参数的构造函数。

作用​:允许通过传递不同参数初始化对象,满足多样化的初始化需求。

特点​:

  • 是最常用的构造函数类型,用于为对象成员赋予初始值。

  • 可重载多个参数化构造函数(参数类型或数量不同)。

示例​:

class Sensor {
public:// 参数化构造函数(带两个参数)Sensor(int id, bool active) : id(id), is_active(active) {}private:int id;bool is_active;
};// 使用场景:创建对象时传递参数初始化
Sensor s2(101, true);  // id=101, is_active=true

3. 拷贝构造函数(Copy Constructor)​

定义​:参数为同类型对象的常量引用​(const T&)的构造函数。

作用​:用一个已存在的对象(源对象)初始化一个新对象(目标对象),实现对象的复制。

关键细节​:

  • 若未显式定义,编译器会生成隐式拷贝构造函数,其行为是浅拷贝​(逐成员复制,对指针成员仅复制地址,不复制指向的内存)。

  • 若类包含动态分配的资源(如堆内存、文件句柄),需显式定义深拷贝的拷贝构造函数,避免多个对象共享同一资源导致重复释放等问题。

示例(浅拷贝 vs 深拷贝)​​:

// 浅拷贝问题示例
class Buffer {
public:Buffer(size_t size) : size(size), data(new uint8_t[size]) {}  // 参数化构造函数~Buffer() { delete[] data; }  // 析构函数释放内存// 隐式拷贝构造函数(浅拷贝):仅复制 data 指针地址// Buffer(const Buffer&) = default; // 显式深拷贝构造函数Buffer(const Buffer& other) : size(other.size), data(new uint8_t[other.size]) {memcpy(data, other.data, size);  // 复制数据内容}private:size_t size;uint8_t* data;
};// 使用场景:对象复制(如传值、返回对象、初始化列表)
Buffer buf1(1024);       // 参数化构造函数
Buffer buf2 = buf1;      // 调用拷贝构造函数(若未定义深拷贝会导致析构时重复释放)

4. 移动构造函数(Move Constructor,C++11 引入)​

定义​:参数为同类型对象的右值引用​(T&&)的构造函数。

作用​:将源对象(通常是临时对象或即将销毁的对象)的资源“转移”到新对象,避免不必要的复制,提升性能。

关键细节​:

  • 若未显式定义,编译器仅在类未显式定义拷贝构造、拷贝赋值、析构函数时,自动生成隐式移动构造函数​(行为是将源对象的成员逐个“移动”,对指针成员直接复制地址,并将源对象指针置空)。

  • 移动构造后,源对象进入“有效但未定义”状态(通常可安全析构或重新赋值)。

示例​:

class DynamicArray {
public:DynamicArray(size_t size) : size(size), data(new int[size]) {}  // 参数化构造函数~DynamicArray() { delete[] data; }// 隐式移动构造函数(编译器自动生成,若未定义其他特殊成员)// DynamicArray(DynamicArray&& other) noexcept //     : size(other.size), data(other.data) {//     other.size = 0;//     other.data = nullptr;  // 关键:置空源对象指针,避免重复释放// }// 显式移动构造函数(优化资源转移)DynamicArray(DynamicArray&& other) noexcept : size(std::exchange(other.size, 0)), data(std::exchange(other.data, nullptr)) {}private:size_t size;int* data;
};// 使用场景:利用临时对象初始化新对象(如 std::move 或函数返回临时对象)
DynamicArray arr1(100);
DynamicArray arr2 = std::move(arr1);  // 调用移动构造函数,arr1 的资源转移给 arr2

5. 委托构造函数(Delegating Constructor,C++11 引入)​

定义​:一个构造函数通过其初始化列表调用同类的另一个构造函数。

作用​:减少重复初始化代码,集中维护初始化逻辑。

关键细节​:

  • 委托构造函数的初始化列表只能调用一个同类的其他构造函数,不能同时初始化成员变量。

  • 避免循环委托(如构造函数 A 调用 B,B 又调用 A),否则会导致编译错误。

示例​:

class Sensor {
public:// 基础构造函数(初始化核心参数)Sensor(int id) : id(id), is_active(true), type("Unknown") {}// 委托构造函数:调用基础构造函数,并初始化额外成员Sensor(int id, const std::string& type) : Sensor(id) {  // 委托给上一个构造函数this->type = type;  // 初始化额外成员}private:int id;bool is_active;std::string type;
};// 使用场景:多个构造函数共享部分初始化逻辑
Sensor s3(202);          // 调用 Sensor(int id)
Sensor s4(203, "Camera"); // 调用委托构造函数,最终调用 Sensor(int id)

6. 转换构造函数(Converting Constructor)​

定义​:单参数的构造函数(或多参数但除第一个外均有默认值),允许将参数类型隐式转换为类类型。

作用​:简化类型转换,使代码更简洁。

注意事项​:

  • 若不需要隐式转换,建议用 explicit关键字修饰,强制要求显式调用构造函数,避免意外的类型转换。

示例​:

class Temperature {
public:// 转换构造函数(单参数,允许 int 隐式转换为 Temperature)explicit Temperature(int celsius) : celsius(celsius) {}  // explicit 禁止隐式转换// 若去掉 explicit:// Temperature(int celsius) : celsius(celsius) {}// 则 int 类型可隐式转换为 Temperature 对象,例如:Temperature t = 25;(可能不符合预期)private:int celsius;
};// 使用场景(显式调用):
Temperature t1(25);       // 正确:显式调用构造函数
// Temperature t2 = 30;   // 错误:因 explicit 禁止隐式转换,需显式调用 Temperature t2(30);

总结表格

构造函数类型

核心作用

关键特性

典型场景

默认构造函数

无参初始化对象

编译器自动生成(若未定义其他构造)

对象无参创建

参数化构造函数

多参数初始化对象

可重载,满足多样化初始化需求

对象带参创建

拷贝构造函数

用已有对象复制初始化新对象

需处理深拷贝(避免资源冲突)

对象复制(传值、返回等)

移动构造函数(C++11)

转移资源而非复制,提升性能

右值引用参数,源对象资源被“窃取”

临时对象初始化、资源转移

委托构造函数(C++11)

减少重复初始化代码

调用同类其他构造函数

多构造函数共享逻辑

转换构造函数

允许参数类型隐式转换为类类型

单参数(或部分默认参数),可用 explicit禁止隐式转换

类型简化转换

注意​:在实际开发(如嵌入式 Linux 或 Qt 应用)中,需根据类的资源管理需求(如是否持有堆内存、文件句柄)选择是否自定义拷贝/移动构造函数,避免资源泄漏或重复释放。对于仅需唯一实例的类(如硬件驱动句柄),可禁用拷贝构造函数(= delete)。

惠州西湖

http://www.dtcms.com/a/407972.html

相关文章:

  • vscode中编写c++程序
  • 深圳企业网站建设与设计制作中安消防安全网站建设
  • 电商网站 设计方案网站开发与维护岗位说明书
  • 网站开发demowordpress建设下载网站
  • Unity-动画子状态机
  • 建设网站用什么软件下载wordpress支持什么格式视频播放器
  • 数据通信与计算机网络—有线局域网:以太网
  • LIN信号对比脚本
  • 渭南自建站网站建设wordpress架设服务器
  • Ansible Playbook 保姆级教程:从基础配置到 Roles 实战,运维自动化必看
  • c 网站开发简单实例设计企业vi
  • 宁夏网站建设哪里有个人品牌营销公司
  • 如何做国外的网站国外优秀门户网站
  • 个人网站 jsp 域名空间网站平台建设咨询合同
  • 栈的学习——逆波兰表达式(RPN)
  • SSM网上点餐系统g582p(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 专业app网站建设遵义企业网络推广方案
  • mysql——用户管理
  • 网博士自助建站系统进贤县住房和城乡建设局网站
  • C语言扫雷游戏
  • 做网站租空间wordpress怎样发布
  • 网站建设优選宙斯站长网站自动识别手机代码
  • 永磁同步电机无速度算法--恒is的调整方法实现IF与SMO间的平滑切换
  • 网站建设评分标准网页游戏新区开服
  • 网站的版面设计邯郸网站设计制作
  • 做个网站 多少钱网站html模板下载
  • 月票车超时配置功能
  • 网站软件下载安装网站建设项目采购公告
  • jsp购物网站开发微信小程序与wordpress
  • AlmaLinux release 9.6服务器离线安装nginx-1.24.0详细步骤