2014-05-15 46 views
1

我碰到過這幾次,我最終刪除了最初的構造函數。我已搜查谷歌,但我甚至不知道這是什麼所謂的...不使用它的構造函數的C++類聲明

class you { 

    private: 
     string name; 
     int number; 
     COLORREF color; 
     drinks favoriteDrink; // here 

    public: 
     you(string Name, int Number, COLORREF Color); 
     string GetName(); 
     int GetNumber(); 
     COLORREF GetColor(); 

}; 

飲料是另一個類和它的構造是這樣的:(INT X,布爾Y)。我想要進一步初始化它。再次,通常我只是刪除構造函數並編寫一個函數ex:init(w/e)。有沒有辦法做到這一點?

回答

5

當你定義一個構造函數時,它可以包含一個成員初始化列表。這是初始化成員和基類的正確方法。所以,你會實現的you的構造是這樣的:

you::you(string Name, int Number, COLORREF Color) : 
    name(Name), 
    number(Number), 
    color(Color), 
    drink(whatever_arguments, you_want) 
{ 
    // body as usual 
} 

請注意,這是唯一方式初始化類的數據成員。如果你不是這樣做:

you::you(string Name, int Number, COLORREF Color) 
{ 
    name = Name; 
    number = Number; 
    color = Color; 
} 

那麼你就不初始化成員,你分配他們。空的成員初始化列表將首先默認 - 初始化它們。這意味着調用類的默認構造函數,併爲初始類型留下未初始化的值。然後,構造函數體通過分配給它們來覆蓋它們。

使用成員初始化列表總是更好,因爲您跳過(無用的)默認初始化。有時,如果您有一個不可分配的成員(例如const成員,一個引用,或者只是一個沒有可訪問賦值運算符的對象),它也是唯一的方法。

1

根據您對使用新建和刪除的感受,以下內容可以實現您所要求的功能。

Angew的方法是最好的方式,如果你知道x和y的足夠早的值,如果以後需要構建favoriteDrink,你可以考慮類似如下:

class drinks; // Forward declare class rather than #including it  

class you 
{  
private: 
    string name; 
    int number; 
    COLORREF color; 
    drinks* favoriteDrink; // Constructor will not be called 

public: 
    you(string Name, int Number, COLORREF Color); 
    ~you(); 
    void someFunction(void); 
    string GetName(); 
    int GetNumber(); 
    COLORREF GetColor();  
}; 

然後在執行:

#include "drinks.h" // Include it now we need it's implementation 

you::you(string Name, int Number, COLORREF Color) : 
    name(Name), 
    number(Number), 
    color(Color), 
    favoriteDrink(NULL) // Important to ensure this pointer is initialised to null 
{ 
    // body as usual 
} 

you::~you() 
{ 
    delete favoriteDrink; // Ok to delete even if it was never newed, because we initialised it to NULL 
    favoriteDrink = NULL; // Always set your pointer to null after delete 
} 

void you::someFunction(void) 
{ 
    favoriteDrink = new drinks(3, 6) // Then once you know your values for x and y 

    // Always check if the pointer is null before using 
    if (favoriteDrink) 
    { 
     // Use the pointer 
    } 
} 

編輯:作爲Angew指出有在C++ 11管理指針的更好的方法,如果你有使用現代編譯器的選項,他的建議將導致更好看和SAF呃代碼。

+0

使用'std :: unique_ptr'或者最好是['boost :: optional'](http://www.boost.org/doc/libs/1_55_0/libs/optional/doc/html/index.html ),會更好。 – Angew

+0

@Angew你說得對,肯定會讓事情變得更安全。我仍然在C++ 98中陷入黑暗時代,而這些東西並不存在。我需要更好地熟悉最近的(!)開發 – rcs

+0

'boost :: scoped_ptr'或者提到的'boost :: optional'也可以在C++ 98/03中工作。 – Angew