面试题答案
一键面试- 返回值优化(RVO,Return Value Optimization)
- 原理:当函数返回一个临时对象时,编译器可以直接在调用者的栈空间上构造这个对象,而不是先在函数内部构造临时对象,然后再将其复制或移动到调用者的栈空间。例如:
在支持RVO的编译器下,上述代码中不会调用复制构造函数和移动构造函数,因为对象直接在class MyClass { public: MyClass() = default; MyClass(const MyClass&) { std::cout << "Copy constructor called" << std::endl; } MyClass(MyClass&&) noexcept { std::cout << "Move constructor called" << std::endl; } }; MyClass createObject() { return MyClass(); } int main() { MyClass obj = createObject(); return 0; }
obj
的位置构造。 - 命名返回值优化(NRVO,Named Return Value Optimization):
- 原理:它是RVO的一种特殊情况,当函数返回的是一个命名的局部对象时,编译器同样可以避免不必要的复制或移动操作。例如:
在支持NRVO的编译器下,同样不会调用复制构造函数和移动构造函数,class MyClass { public: MyClass() = default; MyClass(const MyClass&) { std::cout << "Copy constructor called" << std::endl; } MyClass(MyClass&&) noexcept { std::cout << "Move constructor called" << std::endl; } }; MyClass createObject() { MyClass obj; return obj; } int main() { MyClass result = createObject(); return 0; }
obj
直接在result
的位置构造。 - 复制省略(Copy Elision):
- 原理:这是一个更宽泛的概念,RVO和NRVO都属于复制省略的范畴。除了上述返回值相关的情况,在某些初始化场景下,编译器也可以省略不必要的复制或移动操作。例如,用一个临时对象初始化另一个同类型对象时:
在支持复制省略的编译器下,这里不会调用复制构造函数或移动构造函数,class MyClass { public: MyClass() = default; MyClass(const MyClass&) { std::cout << "Copy constructor called" << std::endl; } MyClass(MyClass&&) noexcept { std::cout << "Move constructor called" << std::endl; } }; int main() { MyClass obj1 = MyClass(); return 0; }
MyClass()
直接在obj1
的位置构造。