C++11默认成员函数控制与右值引用
2026/6/7 1:46:34 网站建设 项目流程

1.默认成员函数

C++ 类会自动生成6 大默认成员函数,C++11 用 =default / =delete 精准控制这些函数。
1.默认构造函数
2.析构函数
3.拷贝构造函数
4.拷贝赋值运算符
5.移动构造函数(C++11)
6.移动赋值运算符(C++11)

关键字作用典型场景
=default让编译器生成默认实现手动写构造后,恢复默认构造
=delete显式禁用该函数禁止类被拷贝(单例模式)

代码示例:

#include <iostream> using namespace std; class Test { public: // 1. 强制生成默认构造函数 Test() = default; // 2. 禁用拷贝(核心:单例模式必用) Test(const Test&) = delete; Test& operator=(const Test&) = delete; // 3. 强制生成默认移动函数 Test(Test&&) = default; Test& operator=(Test&&) = default; }; int main() { Test t1; // Test t2(t1); 报错:拷贝被禁用 Test t3(std::move(t1)); // 正常:移动可用 return 0; }
1.移动构造函数


核心定义:
作用:用一个右值(临时对象)初始化新对象时调用
语法:类名(类名&& 源对象) noexcept;
&&:右值引用,专门绑定临时对象
noexcept:告诉编译器无异常(STL 容器强制要求)
核心逻辑:接管资源 → 把源对象的指针 / 内存拿过来,源对象置空
2. 手写实战(最能理解原理)
我们写一个带动态内存的 String 类,对比拷贝构造和移动构造:

#include <iostream> #include <cstring> using namespace std; class String { private: char* _str; // 动态内存,深拷贝核心 public: // 构造函数 String(const char* str = "") { _str = new char[strlen(str) + 1]; strcpy(_str, str); cout << "构造函数: " << _str << endl; } // 1. 拷贝构造函数(深拷贝:复制一份) String(const String& s) { _str = new char[strlen(s._str) + 1]; strcpy(_str, s._str); cout << "拷贝构造(深拷贝): 复制 -> " << _str << endl; } // 2. 移动构造函数(核心!转移资源,不拷贝) String(String&& s) noexcept { _str = s._str; // 直接接管临时对象的内存 s._str = nullptr; // 源对象置空!防止析构时释放资源 cout << "移动构造(转移资源): 接管 -> " << _str << endl; } // 析构函数 ~String() { if (_str) { delete[] _str; cout << "析构函数" << endl; } } // 打印 const char* c_str() const { return _str; } }; // 测试函数:返回临时对象(右值) String getTempString() { return String("临时对象"); } int main() { // 调用移动构造:用临时对象初始化新对象 String s1 = getTempString(); cout << "s1内容: " << s1.c_str() << endl; return 0; }

运行结果:

✅ 没有执行拷贝构造,直接转移资源,性能拉满!

2、移动赋值运算符


核心定义:
作用:用一个右值给已经存在的对象赋值时调用
语法:类名& operator=(类名&& 源对象) noexcept;
核心逻辑:
1.释放自己当前的资源
2.接管源对象的资源
3.源对象置空
4.返回自身引用

手写实战(接上 String 类)
在上面的类中添加移动赋值运算符:

// 3. 拷贝赋值运算符(深拷贝) String& operator=(const String& s) { if (this == &s) return *this; // 防止自赋值 delete[] _str; // 释放旧资源 _str = new char[strlen(s._str) + 1]; strcpy(_str, s._str); cout << "拷贝赋值(深拷贝)" << endl; return *this; } // 4. 移动赋值运算符(核心!转移资源) String& operator=(String&& s) noexcept { if (this == &s) return *this; // 1. 防止自赋值 delete[] _str; // 2. 释放当前对象的旧资源 _str = s._str; // 3. 接管临时对象资源 s._str = nullptr; // 4. 源对象置空 cout << "移动赋值(转移资源)" << endl; return *this; }

测试移动赋值:

int main() { String s2("已存在的对象"); // 调用移动赋值:临时对象赋值给已存在对象 s2 = getTempString(); cout << "s2内容: " << s2.c_str() << endl; return 0; }

运行结果:

2.右值引用

C++11性能优化核心,解决临时对象拷贝浪费资源的问题。
1. 基础概念


左值:有名字、能取地址、持久存在(如变量int a=10);
右值:临时对象、不能取地址、用完即销毁(如10、函数返回的临时值);
右值引用:&&,专门绑定右值,实现移动语义。


2. 核心作用:移动语义


不拷贝数据,直接接管临时对象的资源(比如字符串的字符数组、容器的内存),性能提升巨大。


3. 关键:std::move ()


将左值强制转为右值引用,触发移动操作。

代码示例:

#include <iostream> #include <string> using namespace std; int main() { string s1 = "hello world"; string s2 = std::move(s1); // 移动:s1把内存交给s2,无拷贝 cout << "s2: " << s2 << endl; // hello world cout << "s1: " << s1 << endl; // 空(资源被移走) return 0; }

扩展:完美转发
std::forward<T>():保留参数的左 / 右值属性,用于通用模板函数,避免类型丢失。

谢谢

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询