一.对象的应用优化、右值引用的优化
文章目录
- 一.对象的应用优化、右值引用的优化
- 1.1 构造,拷贝,赋值,析构中的优化
- 课后练习:
- 1.2 函数调用过程中对象背后调用的方法
- 1.3 对象优化三原则
- 1.4 右值引用、move移动语意、完美转发
1.1 构造,拷贝,赋值,析构中的优化
#include<iostream>
using namespace std;class test
{
public:test(int a = 10) :ma(a) { cout << "test(int)" << endl; }~test() { cout << "~test" << endl; }test(const test& t) :ma(t.ma) { cout << "test(const &)" << endl; }test& operator=(const test& t){cout << "operator=" << endl;ma = t.ma;return *this;}
private:int ma;
};int main()
{test t1;//构造test t2(t1);//拷贝test t3 = t1;//拷贝//临时对象生存周期就是这个语句/*1.C++编译器对于对象构造的优化:用临时对象生成新对象的时候,临时对象就不产生了,直接构造新对象就可以了*/test t4 = test(20);//相当于 test t4(20); 而不是先用临时对象构造,临时对象拷贝,然后临时对象析构,这样效率太低了就给优化了cout << "--------" << endl;t4 = t2;//赋值//2.显式生成临时对象//t4.operator=(const Test &t)这个临时对象会产生,因为要给参数t赋值,传参t4 = test(30);// 依次调用 构造 赋值 析构t4 = (test)30;//有合适的构造函数可以隐式的生成一个临时对象然后给t4,没有合适的就报错//隐式生成临时对象t4 = 30;//这3句等价//3. 临时对象,指针和引用// 指针指向临时对象不安全,但是引用是安全的//p指向的是一个已经析构的临时对象,变成了野指针test* p = &test(40);//但是引用是可以的,因为是起了一个别名,给一块内存重新按了一个名字,就可以继续用,所以是安全的const test& ref = test(50);//4.全局变量是在main函数之前就完成了初始化的//5.test *p1=new test(70) 调用一次构造函数 只有在delete的时候才调用析构//6.test *p2=new test[2] 调用两次构造//7.delete p1 调用析构然后才释放内存//8.delete []p2 两次析构然后调用free释放整个内存 return 0;
}
课后练习:
1.2 函数调用过程中对象背后调用的方法
#include<iostream>
using namespace std;class test
{
public:test(int a = 10) :ma(a) { cout << "test(int)" << endl; }~test() { cout << "~test" << endl; }test(const test& t) :ma(t.ma) { cout << "test(const &)" << endl; }test& operator=(const test& t){cout << "operator=" << endl;ma = t.ma;return *this;}int getData() const { return ma; }
private:int ma;
};test GetObject(test t)//不能返回局部的或者临时对象的指针或引用
{int val = t.getData();test tmp(val);return tmp;
}int main()
{//背后调用了哪些函数呢?test t1;//1.test(int)test t2;//2.test(int)t2 = GetObject(t1);//3.test(const test&) t1->t 实参到形参是一个初始化的过程不是第一个赋值的过程,这里用t1初始化形参t//4.test(int) 初始化tmp// 5.test(const test&) tmp拷贝给一个临时对象//5.tmp 析构//6.t析构//7.operator 赋值 给t2//8.临时对象析构//9.t2析构//10.t1析构return 0;
}
1.3 对象优化三原则
1.函数参数传递过程中,对象优先按引用传递,不要按照值传递(实参到形参不需要构造和析构函数调用)
2.函数返回对象的时候,优先考虑返回一个临时对象,而不是一个定义过的对象
//注意加了引用
test GetObject(test &t)//改成这样以后,调用会少了tmp的构造和析构,又少了两个调用
{int val = t.getData();return test(val);
}
3.接收函数返回值是对象的函数调用的时候,优先按初始化的方式接收,不要按复制的方式接收
#include<iostream>
using namespace std;class test
{
public:test(int a = 10) :ma(a) { cout << "test(int)" << endl; }~test() { cout << "~test" << endl; }test(const test& t) :ma(t.ma) { cout << "test(const &)" << endl; }test& operator=(const test& t){cout << "operator=" << endl;ma = t.ma;return *this;}int getData() const { return ma; }
private:int ma;
};
//注意,加了引用
test GetObject(test &t)//不能返回局部的或者临时对象的指针或引用
{int val = t.getData();test tmp(val);return tmp;
}int main()
{//背后调用了哪些函数呢?test t1;//1.test(int) 构造t1 test t2 = GetObject(t1);//2.test(int) 直接构造t2//3.t2析构//4.t1析构//test t2;//t2 = GetObject(t1);return 0;
}
1.4 右值引用、move移动语意、完美转发
请转至C++11 新特性 学习笔记-CSDN博客进行学习