2011-09-21 171 views
1

我對下面的代碼問題:拷貝構造函數和operator =在C++

讓我們說我有了一個拷貝構造函數和接收一個字符串值常規構造一類p。

我有以下代碼:

P doSomething(){ 
    P p("myValue"); 
    return p; 
} 

int main(){ 
    P m=doSomething(); 
    return 1; 
} 
  1. 爲什麼不拷貝構造函數在doSomething()函數的調用return p
  2. 通話P m=doSomething() - 它想調用拷貝構造函數或操作=?
  3. 的情況下,這是運營商=,就是這段代碼的差異及以下內容:(拷貝構造函數我知道這裏的呼叫)

    P new_val=("newVal"); 
    p m=new_val; 
    

謝謝, 瑪麗

+0

可能重複[爲什麼析構函數被調用一次?(http://stackoverflow.com/questions/ 6422114/why-has-the-destructor-been-called-only-once) –

+0

你可以發佈你在'class P'中定義的拷貝構造函數的代碼嗎? – cpx

+0

在初始化一個變量時,即使您正在編寫'=',也始終使用複製構造函數。關於爲什麼它沒有在你的例子中使用,可能是編譯器優化了你的代碼? – Shahbaz

回答

-2

1)爲什麼複製構造函數在doSomething()函數的「return p」處被調用?

它應該 - 嘗試打印一些東西到複製c-tor中的控制檯,看它是否真的在運行。

2)調用P m = doSomething() - 它是否假設調用複製構造函數或操作符=?

應撥打運營商=。再次,使用調試消息打印從該方法中的情況下,檢查

3)它是操作員=,就是該代碼的差和以下: p新=(「的newval」); P M =新; (我知道這裏的電話是用於複製構造函數的)

你錯過了代碼片段的內容嗎?我認爲它不會編譯

+0

你錯了...... –

+0

噸應該 - 嘗試打印的東西在副本C-TOR控制檯,看看它是否真的不多。 - 我做到了,它不顯示任何信息 – mary

2
  • 爲什麼不在doSomething()函數的返回p處調用複製構造函數?

該標準允許刪除該副本。谷歌爲[N]視網膜靜脈阻塞。在某些編譯器出現這種情況只有在優化,對別人是調用約定的一部分,因此總是會發生的。

  • 調用P m = doSomething() - 它是否假設調用複製構造函數或操作符=?

T t = x;T t(T(x))「語法糖」(在這個意義上,T(x)隱式地發生),因此具有 - 儘管= - 無關operator=。請注意,這裏也將增設臨時可以被省略,因此沒有拷貝構造函數被調用。

  • 的情況下,這是運營商=,就是這段代碼的差異及以下:

這個代碼是沒有意義的,那你究竟意味着什麼?

P new=("newVal"); 
p m=new; 
+0

再點2,它不是相當語法糖:在'T t時的轉換= x'是隱式的(和'explicit'構造將不予考慮);重寫中的轉換是明確的。 (實際上可以編寫代碼,其中兩者都是合法的,但是具有不同的語義,但是這樣的代碼可能是最好的避免。) –

+0

複製初始化和直接初始化並不完全相同。後者甚至可以使用'顯式'拷貝構造函數,前者不會。 –

+0

@JamesKanze:因此,圍繞它的引用,我試圖使答案有點清楚。 – PlasmaHH

0

我做了一個小樣本進行演示。

void print(char* text, int ident) 
{ 
    for(int i = 0 ; i < ident ; i++) 
    { 
     printf(" "); 
    } // end for 

    fprintf(stdout, text); 
    fprintf(stdout, "\n"); 
    fflush(stdout); 
} 

class P 
{ 
public: 
    char* _str; 

    P (P& arg) 
    { 
     print("copy constructor", 2); 
     arg._str = this->_str; 
    } 

    P (char* str) 
    { 
     print("constructor", 2); 
     _str = str; 
    } 
}; 

P doSomething(){ 
    print("do something - function", 1); 
    P p("myValue"); 
    print("before return p", 1); 
    return p; 
} 

int main(int argc, char* argv[]) 
{ 
    print("start", 0); 
    P m=doSomething(); 
    print("stop - call return", 0); 
    return 1; 
} 

這將返回

 
start 
    do something - function 
     constructor 
    before return p 
     copy constructor 
stop - call return 

所以拷貝構造函數會被調用的