2013-05-16 367 views
-4

下面的這段代碼工作正常。在構造函數和析構函數爲什麼我必須將指針初始化爲變量?

#include <iostream> 
using namespace std; 

class CRectangle { 
    int *width, *height; 
    public: 
    CRectangle (int,int); 
    ~CRectangle(); 
    int area() {return (*width * *height);} 
}; 

CRectangle::CRectangle (int a, int b) { 
    width = new int; 
    height = new int; 
    *width = a; 
    *height = b; 
} 

CRectangle::~CRectangle() { 
    delete width; 
    delete height; 
} 

int main() { 
    CRectangle rect (3,4), rectb (5,6); 
    cout << "rect area: " << rect.area() << endl; 
    cout << "rectb area: " << rectb.area() << endl; 
    return 0; 
} 

但爲什麼我不能用另一塊下面的代碼,而不是 //例子嗎?它沒有通過使用下面的代碼編譯,但如果我強制運行它仍然會產生正確的結果。

#include <iostream> 
using namespace std; 

class CRectangle { 
    //here I didn't initialize these two variables' pointers. 
    int width, height; 
public: 
    CRectangle (int a,int b); 
    ~CRectangle(); 
    int area() { 
    return (width * height); 
    } 
}; 

CRectangle::CRectangle (int a, int b) { 
    width = a; 
    height = b; 
} 

CRectangle::~CRectangle() { 

} 

int main() { 
    CRectangle rect (3,4), rectb (5,6); 
    cout << "rect area: " << rect.area() << endl; 
    cout << "rectb area: " << rectb.area() << endl; 
    return 0; 
} 
+3

您無法強制未編譯的代碼運行。你確定你沒有運行最後的成功構建? – chris

+4

'width'和'height'不是指針,所以你應該直接將它們相乘,而不是取消引用它們。你不能刪除它們,因爲你從來沒有分配過它們。 – Barmar

+0

@Barmar說是最正確的做法,而不是第一個。 – chris

回答

3

return (*width * *height);你的第二個代碼段

int area() { 
    return (*width * *height); 
} 

. 
. 
. 

CRectangle::~CRectangle() { 
    delete width; 
    delete height; 
} 

,你提領widthheight這不是指針。另外,在你的析構函數中,你是delete ing widthheight,它們不是用new初始化的指針,因此是無效操作。什麼是正確的是

int area() { 
    return (width * height); // Do not dereference width and height 
} 

. 
. 
. 

CRectangle::~CRectangle() { 
    // Do something else without the deletes or remove the destructor altogether 
} 

而且,什麼@克里斯在他的評論中指出,你也可以刪除析構函數(一定要刪除這兩個宣言和定義)。

+0

的確如此,但是析構函數完全可以完全忽略。 – chris

+0

@chris是的。但我認爲這會在OP方面造成一些混亂。 :) –

+0

更好地清除它現在:)然後我幾乎不需要析構函數。 – chris

1

這裏有一個結構,它包含兩個指向整數的指針,它們必須位於內存中的其他位置。因此,創建CRectangle時,會有三個新對象:CRectangle本身,然後是其他兩個整數。

在面向對象的編程而言,CRectange與兩個int對象經由聚合相關聯。

#include <iostream> 
using namespace std; 

class CRectangle { 
    int *width, *height; 
    public: 
    CRectangle (int,int); 
    ~CRectangle(); 
    int area() {return (*width * *height);} 
}; 

現在這裏,情況就不同了:二int對象被嵌入在裏面CRectangle。當您創建一個CRectangle對象時,這些整數已經存在於其中。它們在內存中有一個地址,所以你可以指向它們,但是它們是相對於地址CRectangle而被訪問的。在CRectangle的成員函數內部,當您訪問width時,它的真正含義是this->width。指向該對象的指針涉及到,但無形中。如果我們有指向對象的指針,那麼它的字段可以通過相對於指針的位移來找到。由於C++不是彙編語言,因此編譯器會爲您計算這種位移計算並生成機器碼。

CRectangle與兩個整數之間的關聯現在是組成

class CRectangle { 
    //here I didn't initialize these two variables' pointers. 
    int width, height; 
public: 
    CRectangle (int a,int b); 
    ~CRectangle(); 
    int area() { 
    return (*width * *height); 
    } 
}; 

area功能,你不應該使用單目運算符*爲指針廢棄,因爲widthheight不是指針。它不適用。 (請確保您的示例在發佈之前乾淨地編譯,除了特別說明一些麻煩的非編譯的示例外。)

相關問題