2012-09-18 68 views
1
class Monitor { 
public: 
    Monitor(string someData); 
    Person person_; 
} 

class Person { 
public: 
    Person(string personId); 
} 

人沒有默認的構造函數。它有一個參數構造函數。 我只能初始化監視器構造函數。 我來自java的聲明只是指針,所以你不需要在聲明時初始化新的實例。c + +我可以聲明類成員,並在構造函數中初始化它

沒有默認構造函數的類成員的最佳做法是什麼? 我應該添加默認的構造函數(缺點 - 不使用它)或使用指針。

回答

7

是的,你可以,你總是應該,通過構造函數初始化列表

class Monitor 
{ 
    Person p; 
    bool state; 
    const int n; 
    double & d; 

    Monitor(std::string const & pname, double & dbl) 
    : p(pname) 
    , state(false) 
    , n(some_other_function(p, state)) 
    , d(dbl) 
    { 
     // constructor body should be as short as possible 
    } 

    // ... 

}; 

正如你所看到的,初始化不只是一個噱頭;相反,這是C++類型系統的一個深刻的必要性:有很多變量,其中必須被初始化並且不能被賦值,比如常量和引用,還有用戶定義的類型,沒有默認構造函數。 (即使有默認構造函數,那麼你需要一個賦值操作符,它在任何情況下仍然是浪費構建你不想要的東西只是覆蓋它片刻之後。)

收費還要注意類組成部分的構建順序:創建類的新實例時,首先按照在類定義中聲明它們的順序構造成員對象,但按照初始化程序列表。在構建所有成員之後,運行構造函數的正文

實際上,還有一件事是在成員對象之前構建的:base子對象。當然,他們的初始太無二在初始化列表中:

struct Foo { Foo(int, bool);    /* ... */ }; 
struct Bar { Bar(std::string const &, int) /* ... */ }; 

class Monitor : public Foo, private Bar 
{ 
    Person p; 

    Monitor(std::string const & pname, int a, int b) 
    : Foo(a, a == b) 
    , Bar(pname, b) 
    , p(pname) 
    { 
     // constructor body 
    } 

    // ... 
}; 

強烈建議(雖然不是強制),你寫在構造函數初始化列表中初始化中,他們將執行相同的順序!

+0

我只能在Monitor構造函數中初始化它。 –

+0

@ user1495181:做一個輔助函數,就像我爲'n'做的那樣! –

相關問題