MST

星途 面试题库

面试题:C++ 中按值传递参数复制优化的基础机制

在C++中,简述按值传递参数时,编译器通常会进行哪些复制优化技术?请至少列举两种常见的优化机制,并简要说明其原理。
20.2万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 返回值优化(RVO,Return Value Optimization)
    • 原理:当函数返回一个临时对象时,编译器可以直接在调用者的栈空间上构造这个对象,而不是先在函数内部构造临时对象,然后再将其复制或移动到调用者的栈空间。例如:
    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;
    }
    
    在支持RVO的编译器下,上述代码中不会调用复制构造函数和移动构造函数,因为对象直接在obj的位置构造。
  2. 命名返回值优化(NRVO,Named 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() {
        MyClass obj;
        return obj;
    }
    
    int main() {
        MyClass result = createObject();
        return 0;
    }
    
    在支持NRVO的编译器下,同样不会调用复制构造函数和移动构造函数,obj直接在result的位置构造。
  3. 复制省略(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的位置构造。