首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 複製構造函數調用次數:傳值參數 + 返回值 = 兩次(未優化時)

     編輯:程式設計綜合問答

代碼驗證

#include <iostream>
using namespace std;

class A {
public:
    A() { cout << "A()\n"; }
    A(const A& a) { cout << "A(const A&)\n"; }
};

void foo(A a) { }  // 參數按值傳遞

int main() {
    A a;      // 1. 默認構造
    foo(a);   // 2. 複製構造傳參
              // 3. 函數結束銷毀參數
    return 0;
}
// 輸出:
// A()
// A(const A&)   ← 這裡
// A(const A&)   ← 這裡(返回值優化 RVO 可能消除)

兩次複製的來源

  1. 實參 → 形參:調用 foo(a) 時,按值傳遞觸發複製構造。
  2. 返回值 → 調用處:若函數返回 A(非引用),臨時對象構造後再複製給調用方(C++17 前)。

現代 C++ 優化機制

優化標準效果
RVO (Return Value Optimization)C++98/11編譯器直接在調用方棧框構造返回對象,**消除返回值複製**
NRVO (Named RVO)C++11具名變量返回時同樣優化
強制移動語義C++11返回右值引用 A&& 或依賴移動構造(若類定義)
拷貝省略C++17強制要求編譯器省略臨時對象複製,**不再依賴優化**

最佳實踐

  1. 參數傳 const 引用:void foo(const A& a) 避免第一次複製。
  2. 返回值按值返回:信任 C++17 拷貝省略,寫 A create() { return A(); }。
  3. 定義移動構造/賦值:A(A&&) noexcept,讓不可省略時也能高效移動。
  4. 禁用複製:若類不可複製,delete 複製構造,僅支持移動。

面試必答口訣

「C++98 兩次,C++11 RVO 可能一次,C++17 強制零次(拷貝省略)。實戰中:參數用 const&,返回用值,定義 noexcept 移動構造。」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved