|
//深入学习c++(类的c++11后三个基本原则变成了五个基本原则)
//c++11中可以严格区分左值与右值!
//对于一个带有资源的类 深拷贝的
//原则:1、构造new析构delete 2、拷贝构造函数 3、operator=重载
// 4、[针对右值]拷贝构造函数 5、[针对右值]operator=重载
C++中的类 :绝对不要在析构函数里面抛出异常
所以:默认的析构函数都添加了关键字 noexcept
原因:
1、C++无法同时捕获多个异常 一个try{}catch{}只能一个异常
A、多个实例 或 B、多个基类的析构抛异常
2、导致类的有些资源无法释放,内存泄露
c++(类 构造函数失败应该抛出异常)
- #include <iostream>
- #include <vector>
- #include <string.h>
- #include <cassert>
- using namespace std;
- class Teacher
- {
- private:
- int m_age;
- char* m_name; //字符指针 资源
- public:
- Teacher(int age, char* pname){
- m_age = age;
- m_name = new char[strlen(pname) + 1];
- strcpy(m_name, pname);
- }
- void print_info() const{
- assert(m_name);
- printf("老师的年龄:%d,名字:%s\n", m_age, m_name);
- }
- Teacher(const Teacher& other){
- //拷贝构造函数 Teacher& other 不带const就只能是左值的拷贝构造了
- printf("调用拷贝构造函数,不带const就只能是左值的!\n");
- m_age = other.m_age;
- m_name = new char[strlen(other.m_name) + 1];
- strcpy(m_name, other.m_name);
- }
- Teacher(Teacher&& other){
- //【右值的】拷贝构造函数
- printf("调用【右值的】拷贝构造函数!\n");
- // 右值一般都是临时变量 操作完后就不用了的 利用右值减少拷贝
- m_age = other.m_age;
- m_name = other.m_name;
- other.m_name = nullptr;
- other.m_age = -1;
- }
- Teacher& operator=(const Teacher& other){
- printf("调用operator=重载,不带const就只能是左值的!\n");
- m_age = other.m_age;
- delete [] m_name; //先释放左边的资源
- m_name = new char[strlen(other.m_name) + 1];
- strcpy(m_name, other.m_name);
- return *this;
- }
- Teacher& operator=(Teacher&& other){
- //Teacher&&代表是右值的引用
- printf("调用【右值的】operator=重载!\n");
- if(&other == this){
- // t1 = std::move(t1);这种情况下
- return *this;
- }
-
- delete [] m_name; //记得先释放左边的资源
- // m_name = new char[strlen(other.m_name) + 1];
- // strcpy(m_name, other.m_name);
- m_name = other.m_name;
- m_age = other.m_age;
- other.m_name = nullptr;
- other.m_age = -1;
- return *this;
- }
- ~Teacher(){
- printf("调用老师%s析构函数!\n", m_name);
- delete [] m_name;
- m_age = -1;
- }
- };
- //深入学习c++(类的c++11后三个基本原则变成了五个基本原则)
- //c++11中可以严格区分左值与右值!
- //对于一个带有资源的类 深拷贝的
- //原则:1、构造new析构delete 2、拷贝构造函数 3、operator=重载
- // 4、[针对右值]拷贝构造函数 5、[针对右值]operator=重载
- int main(){
- Teacher t1(30, "jingjinju");
- Teacher t2(33, "izengzhi");
- // c++11中严格区分了 左值与右值 能取地址的就是左值
- //std::move(t1) 就是将左值转为右值
- // 编译器有能力区分 左值还是右值的 拷贝构造函数 operator=
- Teacher t3 = std::move(t1);
- //特别注意:std::move()调用之后 t1的m_name变null了 t1的资源已经被抽干了
- // t1.print_info();
- t1 = std::move(t2);
- return 0;
- }
复制代码
|
|