Wmeng0 2020-06-14
一、产生临时对象的情况和解决方案
1、以传值的方式给函数传递参数
一般以传引用的方式来传递参数,可以少调一次构造函数和析构函数
2、类型转换生成的临时对象/隐式类型转换以保证函数调用成功
类型转换生成的临时对象
class Element { int m_val; Element(int val = 10) : m_val(val) { } } Element ele; // 调用一次默认构造函数 ele = 100; // 调用一次构造函数, 调用一次拷贝赋值函数,调用析构函数 // 说明这句话会先构造一个临时变量,再将临时变量拷贝给ele Element ele = 100; // 只会调用一次构造函数,直接用100来构造ele对象,构造在ele的预留空间中,不会生成临时对象,
隐式类型转换以保证函数调用成功
void Func(Element& ele); void Func2(const Element& ele); Func(100); // 编译失败 Func2(100); // 编译成功,系统会将100转换成一个临时对变量,再传给函数Func2 // C++只会为const引用隐式类型转换产生临时变量,而不会为非const引用产生临时变量
3、函数返回对象
Element Func() // 该函数返回temp时,调用拷贝构造函数构造一个临时变量 { Element temp; // 调用了一次构造函数 return temp; // 返回时会调用一次拷贝构造函数 } Func(); // 当临时变量没有被接住的时候,会自动释放掉 Element ele = Func(); // 当临时变量被变量接住时,拷贝构造函数会直接在ele的预留空间中进行构造 // 函数优化。如果函数满足优化条件,即可以直接返回构造函数 Element Func() { return Element(); // 直接返回构造函数, // 这样操作只会调用一次构造函数来构造临时变量,不会调用拷贝构造函数,节省了一次拷贝和临时变量的析构 }
二、移动构造函数
// 格式: Element(Element && elem) noexcept : 初始化列表 // noexcept:通知标准库我们这个移动构造函数不抛出任何异常(提高编译器效率),一般情况下,移动构造函数都要加这个关键字,可以提高编译器效率 // 当用户自定义了移动构造函数之后,原来函数返回值的临时变量调用拷贝构造函数的情况,都会自动调用移动构造函数,但是具体操作需要自己实现
是一道经常出现在前端面试时的问题。如果只是简单的了解new关键字是实例化构造函数获取对象,是万万不能够的。更深入的层级发生了什么呢?同时面试官想从这道题里面考察什么呢?下面胡哥为各位小伙伴一一来解密。