2013-03-25 36 views
1

我在由參考和值到特定類的功能通過對象之間的差異混淆。如果我按值傳遞對象,我知道默認的拷貝構造函數使得對象的成員由成員副本在給定的功能使用。但是,如果我將對象作爲需要深度複製的類的const引用傳遞,複製構造函數是否仍然被調用?說我有一個功能構造函數調用和物體通過

 void debug(const MyClass& object1); 

會通過object1調用複製構造函數嗎?或者是對象直接傳遞給函數而沒有創建副本?還有一個問題 - 如果我有一個叫Fraction-

 Fraction A(1,2); // 1 is this numerator, 2 the denominator 

    A = Fraction(2,3); 

是否在上述行調用默認構造函數來創建一個臨時目標級(2,3),然後賦值運算符?

謝謝。

回答

2

Would passing object1 call the copy constructor?

不,它不會調用拷貝構造函數,因爲通過參照 沒有副本,在這種情況下

A = Fraction(2,3); 

是做,它會調用帶兩個參數的構造函數(或默認構造函數,如果兩個參數都有默認值),然後調用複製賦值操作符。

你可以看到從下面的代碼輸出:

#include <iostream> 
using namespace std; 
class Fraction 
{ 
    public: 
    int denom; 
    int nominator; 
    Fraction(int d , int n):denom(d), nominator(n) 
    { 
    cout << "call non-copy constructor" <<endl; 
    } 

    Fraction(const Fraction& rhs) 
    { 
    cout << "call copy constructor" <<endl; 
    denom = rhs.denom; 
    nominator = rhs.nominator; 
    } 

    const Fraction& operator=(const Fraction& rhs) 
    { 
    cout << "call copy assignment operator" << endl; 
    if (this == &rhs) 
    { 
     return *this; 
    } 

    denom = rhs.denom; 
    nominator = rhs.nominator; 
    return *this; 
    } 
}; 

void debug(const Fraction& obj) 
{ 
    cout << "this is debug: pass by reference " <<endl; 
} 

void debugPassByValue(Fraction obj) 
{ 
    cout << "this is debug: pass by value" <<endl; 
} 

int main() 
{ 
    Fraction A(1,2); 
    cout << "--------------" <<endl; 
    debug(A); 
    cout << "--------------" <<endl; 
    A = Fraction(2,3); 
    cout << "--------------" <<endl; 
    debugPassByValue(A); 
    cout << "--------------" <<endl; 
    cin.get(); 
    return 0; 

}

您將看到以下的輸出:

call non-copy constructor //Fraction A(1,2); 
-------------- 
this is debug: pass by reference //debug(A); 
-------------- 
call non-copy constructor //A = Fraction(2,3);---> construct temporary object 
call copy assignment operator //A = Fraction(2,3); 
-------------- 
call copy constructor //debugPassByValue(A); 
this is debug: pass by value 
-------------- 

現在你將有什麼是所謂的一個更清晰的視野。

1

事實上在debug的情況下,沒有副本。

在第二種情況下,我不能肯定我明白你的問題。此行:

A = Fraction(2,3); 

應使用Fraction的賦值運算符。 A已經存在,所以它使用的實例A賦值運算符爲其分配Fraction(2,3)這是一個臨時的對象。

+0

對不起,我不是很明確。我真的想知道是否調用構造函數來構造臨時對象Fraction(2,3),然後通過默認賦值運算符將其分配給A. – jonnywalkerr 2013-03-25 02:29:14

2

在下文中,我們將考慮[x]意味着x是可選的。

我對通過引用傳遞的對象和對特定類的函數的價值之間的差異感到困惑。

當您按值傳遞對象時,程序必須創建該函數的本地對象,因此它會調用該類的複製構造函數以創建此對象。當你通過引用傳遞(並且似乎通過指針)函數內部的變量object1只是傳遞給函數的對象的別名;因此,如果編輯函數內的編輯,編輯也將應用於外部對象。

上述行是否調用默認構造函數來創建一個臨時對象Fraction(2,3)然後賦值操作符?

這是賦值運算符。考慮到AX類型的已聲明變量,它將被稱爲X Fraction::operator=([const] Fraction[&])或任何兼容類型。

注:聲明Fraction x = Fraction(2, 3)時,它不會被使用的operator=,你可能期望的,對應的構造將改爲調用(在這種情況下Fraction::Fraction([const] Fraction[&]))。

+0

因此,對於我自己的教化,通過引用傳遞對象或作爲函數的const引用不會調用複製構造函數。在任何一種情況下,對象都是別名,唯一的區別是const引用不會是可變的。它是否正確? – jonnywalkerr 2013-03-25 02:31:58

+0

@Jonnywalkerr,是的,這是正確的。實際上'const'引用的'const'部分可以很容易地用'constant_cast'向下轉換,但是,它不應該是可變的。 – Shoe 2013-03-25 02:34:57