2013-03-11 36 views
1
#include <iostream> 
#include <cstring> 
using namespace std; 

class foo { 
    int number; 
    char string[20]; 
public: 
    foo() { 
      set(3, 5); 
    } 
    void set (int a, int b) { 
      number = a + b; 
     strcpy(string, "summer"); 
    } 

    foo (const foo & c) { 
    } 

    void output() { 
      cout << number << ',' << string << endl; 
    } 
}; 

void showyanothing (foo); 

int main() { 
    foo a, b; 
    showyanothing(a); 
    a.output(); 
    b.output(); 
} 

void showyanothing (foo z) { 
    cout << "... how are you?\n"; 
    z.output(); 
} 

輸出複製構造和複製值到對象

... hello ... 
... how are you? 
-1218897013,l·ôl·Y·ôl·À 
8,summer 
8,summer 

-1218897013,l·ôl·Y·ôl·À的線,這些都是在由拷貝構造創建的對象的Z值。如果我將我的拷貝構造函數更改爲以下內容,則輸出對象z將生成10, summer.1.2.3。爲什麼?神奇的價值從哪裏插入Z?

新的拷貝構造函數

foo (const foo & c) { 
    number = c.number + 2; 
    strcpy(string, c.string); 
    strcat(string, ".1.2.3"); 
} 

新的輸出:

... how are you? 
10,summer.1.2.3 
8,summer 
8,summer 

在拷貝構造函數,我感到困惑的是,爲什麼c.number等同於8和c.string等號到了夏天?它從哪裏獲得這些價值?

回答

4

簡單的檢查了函數調用

void showyanothing (foo z) 

複製構造函數調用這裏。由於在前面的代碼中有複製構造函數,並且沒有初始化數據成員,因此它會打印隨機值。在另一方面,當你編輯的拷貝構造函數,你得到的結果(即調用下面!)

foo (const foo & c) { 
    number = c.number + 2; 
    strcpy(string, c.string); 
    strcat(string, ".1.2.3"); 
} 

希望能解決您的疑問:)

+0

我明白,但不是foo&c引用z,其中z是空的,所以c.number什麼都不是?只是困惑如何c.number持有8和c.string持有夏季。 – eveo 2013-03-11 03:59:30

+0

如果您在代碼中看到既有默認構造函數也有複製構造函數。創建對象時將調用默認的構造函數。然後,當進行函數調用時,調用複製構造函數(查看函數簽名)。現在比較兩個代碼:) – NirmalGeo 2013-03-11 04:04:56

0

你的拷貝構造函數的第一個版本不初始化foo的成員變量。因此,numberstring將包含隨機數據 - 不管發生在新對象被實例化的位置的RAM中。

第二個版本根據通過引用傳入的對象(我們應該「複製」的對象)正確地將值分配給成員變量。在這種情況下,您傳遞的是a(因爲您調用showyanothing(a)),它已使用默認構造函數實例化,該構造函數爲數字8和字符串「summer」。

0

無論是否初始化,對象都佔用內存。內存包含一些任意值。如果你不初始化它,它可以是任何東西。這解釋了你得到的初始垃圾輸出。

接下來,您將提供合理的複製構造函數,它根據傳遞給它的源對象初始化對象。在您的main()開始時,您創建了使用默認構造函數構造的對象a,並因此調用set(3,5)調用,從而將其number成員設置爲8。 showyanothing (foo z)函數獲取通過值傳遞的參數,這意味着使用複製構造函數創建類foo的新實例,該構造函數接收對象a,它將anumber(它是8)和string的副本相加。