亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么在這種情況下不調用復制構造函數?

為什么在這種情況下不調用復制構造函數?

C++
猛跑小豬 2019-07-17 18:41:23
為什么在這種情況下不調用復制構造函數?下面是代碼片段:class A{public:     A(int value) : value_(value)     {         cout <<"Regular constructor" <<endl;     }     A(const A& other)   : value_(other.value_)       {         cout <<"Copy constructor" <<endl;     }private:     int value_;};int main(){     A a = A(5);}我假設輸出將是“常規構造器”(對于RHS),其次是LHS的“復制構造函數”。因此,我避免了這種樣式,并且總是將類的變量聲明為A a(5);..但令我驚訝的是,在上面的代碼中,從來沒有調用過復制構造函數(Visualc+2008)。有沒有人知道這種行為是編譯器優化的結果,還是C+的一些有文檔的(和可移植的)特性的結果?謝謝。
查看完整描述

3 回答

?
回首憶惘然

TA貢獻1847條經驗 獲得超11個贊

我研究這個問題是為了回答另一個問題,這個問題是以欺騙的形式結束的,所以為了不讓工作白費,我會回答這個問題。

表格的陳述A a = A(5)被稱為復制初始化變量的a..8.5/16的C+11標準規定:

使用初始化器表達式作為參數調用所選函數;如果函數是構造函數,則調用初始化目標類型的cv非限定版本的臨時函數。臨時值是一個prvalue。然后,根據上述規則,調用的結果(是構造函數用例的臨時結果)被用于引導初始化副本初始化的目標對象。在某些情況下,允許實現通過將中間結果直接構造到被初始化的對象來消除這種直接初始化過程中固有的復制;參見12.2,12.8。.

這意味著編譯器查找要處理的適當構造函數。A(5),創建一個臨時的,并將該臨時副本復制到a..但是,在什么情況下,復制可以被刪除呢?

讓我們看看12.8/31是怎么說的:

當滿足某些條件時,即使對象的復制/移動構造函數和/或析構函數有副作用,也允許實現省略類對象的復制/移動構造。在這種情況下,實現將省略的復制/移動操作的源和目標視為引用同一對象的兩種不同方式,并且該對象的銷毀發生在如果不進行優化就會銷毀這兩個對象的晚些時候。復制/移動操作的簡化,稱為復制省略,允許在下列情況下(可合并以消除多份副本):

[...]

  • 當沒有綁定到引用(12.2)的臨時類對象被復制/移動到具有相同cv-非限定類型的類對象時

    ,可以通過將臨時對象直接構造到省略的復制/移動的目標中來省略復制/移動操作。

考慮到所有這些,下面是表達式的結果A a = A(5):

  1. 編譯器會看到帶有復制初始化的聲明。
  2. 這個

    A(int)

    構造函數以初始化臨時對象。
  3. 因為臨時對象是

    綁定到引用,并且它確實具有相同的類型。

    A

    作為復制初始化表達式中的目標類型,編譯器可以直接將對象構造為

    a

    ,臨時的


查看完整回答
反對 回復 2019-07-17
?
慕勒3428872

TA貢獻1848條經驗 獲得超6個贊

A a = A(5);

這一行相當于

A a(5);

盡管它的功能樣式外觀,第一行簡單地構造a與論點5。不涉及抄襲或臨時人員。來自C+標準的第12.1.11節:

函數符號類型轉換(5.2.3)可用于創建其類型的新對象。[注意:語法看起來像構造函數的顯式調用。-尾注]


查看完整回答
反對 回復 2019-07-17
  • 3 回答
  • 0 關注
  • 364 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號