2013-03-24 181 views
2

我正在學習使用練習考試的C++考試。我在確定何時調用某些構造函數時遇到問題。代碼是 -默認構造函數調用

using namespace std; 
#include <iostream> 

class Fraction 
{ 
    private: 
    int numerator, denominator; 
    public: 
    Fraction(int = 0, int = 1); 
    friend ostream& operator<<(ostream&, const Fraction&); 
    }; 

void debug(Fraction, Fraction); 
Fraction task(Fraction&, const Fraction&); 

int main() 
    { 
    Fraction * A[6], * B; // Line 1 
    Fraction C(3), D(C); // Line 2 
    Fraction E[4], F = D; // Line 3 
    Fraction G, H(3, 4); // Line 4 
    debug(C, D); // Line 5 
    B = new Fraction; // Line 6 
    F = task(H, C); 
    delete B; 
    return 0; 
    } 

void debug(Fraction X, Fraction Y) 
{ 
    cout << X << endl << Y << endl; 
} 

Fraction task(Fraction& X, const Fraction& Y) 
{ 
    Fraction Z; 
    Z = Fraction(5, 2); // Line 7 
    return 1; // Line 8 
} 

現在,我認爲在3種類型的實例中調用默認的複製構造函數。

實施例1 -

 Fraction A(1,2); 

     Fraction B(A); 

實施例2 -

 Fraction A(1,2); 

     Fraction A = B; 

3 - 當一個對象被作爲參數傳遞到 - 當一個對象從一個函數

4返回功能

有兩個問題,我似乎無法回答 -

問題1 - 考慮上面的源代碼。當編譯並執行標記爲「第3行」和「第4行」的 語句時,將針對這些語句中的每個 對構造函數調用類「分數」多少次?

答案是 - d)線路3:5個通話線路4:2個來電

的這個問題的答案是D.然而,當我回答這個問題,我得到不同的結果 -

Fraction E[4], F = D; // Line 3 

我看到默認的構造函數被調用5次,E [4],但我認爲這這種說法也相當於陣列 -

Fraction E[4], Fraction F(D); 

因此,默認構造函數被調用5次,複製構造函數一次。顯然,這是不正確的,因爲構造函數只被調用5次。我沒有看到我的錯誤在哪裏。

我的另一個問題是在以下問題 -

  1. 考慮(上頁)圖2中的源代碼。當編譯並執行標記爲「第7行」和「第8行」的 語句時,將針對這些語句中的每個 對構造函數調用類「分數」多少次?

    答案是 - d)7號線:1次通話中的線路8:1的呼叫

    Fraction task(Fraction& X, const Fraction& Y) 
        { 
         Fraction Z; 
         Z = Fraction(5, 2); // Line 7 
         return 1; // Line 8 
        } 
    

    我原本以爲默認構造函數將被調用,以創建分數(5,2一個臨時對象)那麼複製構造函數會將Fraction(5,2)複製到Z.這實際上是默認賦值運算符的操作嗎?至於第8行,這是調用複製構造函數,因爲它正在返回一個Fraction類型的對象?

一些問題,而我在這裏 -

會 -

debug(B, C) 

調用拷貝構造函數兩次通過分數對象B和C的副本?

是 -

F = task(H, C); 

調用默認的賦值運算符,以及爲F已作爲初始化Fraction對象?

+0

爲什麼不在調試器中運行此代碼? – 2013-03-24 02:03:36

+0

對不起,如果這不能回答你的問題。該程序正在使用默認的構造函數。我試圖在默認的構造函數被調用時做筆記。如果有一個調試器會告訴我,那會很好。不過,我想明白爲什麼我會佔用更多的電話而不是分配問題的答案。就像第3行一樣,我只是爲了一個電話而不是答案。關於我的邏輯的東西是錯誤的。 – jonnywalkerr 2013-03-24 02:08:28

+0

你的代碼是否被編譯?至少不在g ++ 4.7.2 – gongzhitaao 2013-03-24 02:10:27

回答

1

你基本上想知道什麼時候調用默認的構造函數和拷貝構造函數。

關於第一個問題:

Fraction E[4], F = D; // Line 3 

E[4]Fraction對象的數組,它調用默認的構造函數的4倍,因爲你沒有顯式調用任何其它的構造函數初始化的對象。由於在第2行對象D已經構建,因此,F是使用複製構造函數構造的,在這種情況下,編譯器會爲您生成一個,因爲您沒有爲自己定義一個。 所以在這種情況下,4個默認構造函數調用和一個拷貝構造函數調用。 在第4行,兩個對象都調用默認的構造函數,所以在默認的ctor上調用兩次。

debug(B, C) 
call the copy constructor twice to pass copies of Fraction objects B and C? 

是的,因爲參數是按值在debug功能過去了,所以拷貝構造函數被調用這兩個BC

在一般情況下,拷貝構造函數調用在以下情況:

  1. 當使用現有對象實例化一個對象時(如F= DF(D)
  2. 當傳遞一個物體的價值。
  3. 通過值從函數返回對象時。

希望這給你足夠的信息來理解代碼。

+0

謝謝。似乎我忘記了聲明數組的容量是顯式的,而不是元素的數量+ 1。如果我可能會問,說我聲明Fraction F(1,2),然後複製一個現有的對象,比如F =分數(3,4)。這會調用默認的構造函數和默認賦值運算符嗎? – jonnywalkerr 2013-03-24 02:15:12

+0

@Jonnywalkerr Fraction(1,2)將調用默認構造函數,F(3,4)也會調用默認構造函數。由於F已經創建,所以F = Fraction(3,4)將調用複製賦值操作符,編譯器在這種情況下爲您生成。 – taocp 2013-03-24 02:30:14

+0

因此,編譯器同時生成一個拷貝構造函數和一個拷貝賦值操作符。調用複製構造函數來處理將數據成員從一個成員逐個成員複製到新聲明的對象。這與默認賦值運算符的區別在於賦值運算符將項目中的項目複製到已經初始化的對象。它是否正確?另外,對於像F = Fraction(3,4)這樣的東西,它只是複製賦值操作符被調用嗎?或者是默認的構造函數,以及生成一個臨時對象Fraction(3,4)? – jonnywalkerr 2013-03-24 03:38:46