C++拷贝构造函数和移动构造函数(修订版)
创作时间:
作者:
@小白创作中心
C++拷贝构造函数和移动构造函数(修订版)
引用
CSDN
1.
https://blog.csdn.net/Lzy1154119938/article/details/139480054
在C++编程中,拷贝构造函数和移动构造函数是管理对象生命周期的关键机制。本文将深入探讨这两个构造函数的定义、使用场景以及最佳实践,帮助开发者更好地理解它们的工作原理和应用场景。
C++中的拷贝构造函数和移动构造函数(修订版)
在C++中,拷贝构造函数(Copy Constructor)和移动构造函数(Move Constructor)是两个非常重要的特性,用于对象的复制和移动操作。本教程将详细介绍这两个构造函数的定义、用法和最佳实践。
拷贝构造函数
定义
拷贝构造函数是用来创建一个对象,该对象是使用另一个同类型的对象初始化的。拷贝构造函数的原型如下:
ClassName(const ClassName& other);
什么时候会调用拷贝构造函数?
- 通过值传递对象时:函数参数是对象类型,并且以值传递。
- 返回局部对象时:函数返回一个局部对象。
- 用一个对象初始化另一个对象时。
示例
#include <iostream>
#include <cstring>
class MyString {
private:
char* data;
public:
// 构造函数
MyString(const char* str = nullptr) {
if (str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
} else {
data = new char[1];
data[0] = '\0';
}
}
// 拷贝构造函数
MyString(const MyString& other) {
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
// 打印函数
void print() const {
std::cout << data << std::endl;
}
// 析构函数
~MyString() {
delete[] data;
}
};
int main() {
MyString str1("Hello");
MyString str2 = str1; // 调用拷贝构造函数
str2.print();
return 0;
}
移动构造函数
定义
移动构造函数用于通过“移动”资源来构造一个新的对象,而不是复制。移动构造函数的原型如下:
ClassName(ClassName&& other);
什么时候会调用移动构造函数?
- 用临时对象初始化另一个对象时。
- 函数返回一个对象时,如果返回值被用于初始化另一个对象。
- 标准库容器在需要移动元素时。
示例
#include <iostream>
#include <cstring>
class MyString {
private:
char* data;
public:
// 构造函数
MyString(const char* str = nullptr) {
if (str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
} else {
data = new char[1];
data[0] = '\0';
}
}
// 拷贝构造函数
MyString(const MyString& other) {
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
// 移动构造函数
MyString(MyString&& other) noexcept {
data = other.data;
other.data = nullptr; // 使other对象处于有效但未指定状态
}
// 打印函数
void print() const {
if (data) {
std::cout << data << std::endl;
} else {
std::cout << "data is null" << std::endl;
}
}
// 析构函数
~MyString() {
delete[] data;
}
};
int main() {
MyString str1("Hello");
MyString str2 = std::move(str1); // 调用移动构造函数
str2.print();
str1.print(); // str1的数据被移动,所以它的data指针为null
return 0;
}
拷贝构造函数和移动构造函数的比较
拷贝构造函数
- 效率低:拷贝构造函数涉及深拷贝,复制数据,需要更多的内存和时间。
- 使用场景:当需要独立的对象副本时。
移动构造函数
- 效率高:移动构造函数通过移动资源(如指针)来构造对象,避免了不必要的数据复制。
- 使用场景:当对象所有权可以被转移时,例如处理临时对象或从函数返回对象时。
规则和最佳实践
- Rule of Three/Five:如果你定义了一个拷贝构造函数、赋值操作符或析构函数,你应该显式定义所有这三个。对于C++11及以后,如果你定义了一个拷贝构造函数、赋值操作符、析构函数、移动构造函数或移动赋值操作符,你应该显式定义所有五个。
- 优先使用移动构造函数:对于临时对象或需要转移资源的情况,优先使用移动构造函数以提高效率。
- 提供 noexcept:对于移动构造函数,使用
noexcept可以帮助标准库优化性能。
总结
在C++中,拷贝构造函数和移动构造函数是对象管理的重要部分。理解并正确使用它们可以显著提升程序的性能和可靠性。希望通过本教程,你能够更好地掌握这两个构造函数的使用技巧。
热门推荐
Excel中快速自动填充数字的多种方法
中农大高油669玉米品种简介
正宗那不勒斯披萨制作大冒险 —— 让舌尖畅游地中海的绝妙旅程
山西煎饼制作全攻略|煎饼制作技巧
男性为什么会尿频?长期尿频有什么危害?
多地餐饮商家推行"小份菜",杜绝"舌尖上的浪费"!
黑神话悟空大圣残躯:探寻游戏背后的故事与深度解析
月相之变化有什么规律,易者焉能不知?
北京烤鸭的历史与文化探究
游戏玩家CPU选购指南,需求与预算兼顾
四川公认18市3州各自的代表性早餐!1.龙抄手—代表地:成都
民国四大影后之阮玲玉:25岁被逼自杀身亡,害她的男人后来怎样了
“蛇”在语言与文化中的多重象征意义与隐喻分析探讨
好莱坞特效在中式大片中的水土不服
药师说药丨“点滴”背后的真相:药师为您细述静脉输液的双刃剑效应
唐朝开国八大功臣:李渊杀3个,李世民斩4个,最后一位啥下场?
2025年住房租赁市场洞察:武汉篇
每天吃二甲双胍,为什么血糖降不下来?服药方式很重要
清光绪年间,两位新娘被错抬,结局却远没有小说中那般幸运
深入分析汽油价格差异的原因及其在市场供需中的体现
什么是亡灵节?Día de los Muertos的问候,诗歌和名言
了解蝴蝶犬——一只可爱的宠物(探秘蝴蝶犬的外貌特征及饲养要点)
VMware虚拟机桥接无线网卡上网的解决方案及网络模式详解
巴黎续约阿什拉夫双赢,恩里克长期打造,欧冠赛事不容有失
成都天台山晋升5A!全国19家景区获新评定
直通南马,起点奥体中心!2025南京半程马拉松报名开启
PS教你如何去掉图片中多余的人物,你学会了么?
查理·芒格的投资智慧:跨学科思维与长期投资的力量
一部印刷史见证版权保护起源
母婴用品选购指南:安全与实用并重