2012-07-24 247 views
2

從Java發出,我對下面的代碼有困難。 在我的理解中,b只是在第3行聲明,但沒有實例化。聲明與實例化

什麼是在A類中創建B實例的文本書方式?

class A { 
    private: 
    B b; 
    public: 
    A() { 
     //instantiate b here? 
    } 
}; 

編輯:如果B沒有默認的構造函數呢?

+1

它在構造函數體啓動之前自動完成(如果B具有可訪問的默認構造函數)。 – jrok 2012-07-24 13:03:48

+0

@jrok謝謝,因此對於使用默認構造函數生成的任何實例,上面的代碼都很好? – user695652 2012-07-24 13:05:40

+0

是的。對於你的編輯的答案看到juanchopanzas答案。 – jrok 2012-07-24 13:09:30

回答

9

你可以明確地初始化A的構造函數的初始化列表b,例如

class A { 
    B b; // private 
public: 
    A : b() {} // the compiler provides the equivalent of this if you don't 
}; 

然而,b會得到自動反正實例化。以上是有道理的,如果你需要建立一個B使用非默認的構造函數,或者如果B不能缺省初始化:

class A { 
    B b; // private 
public: 
    A : b(someParam) {} 
}; 

它可能無法在構造函數的初始化列表中正確初始化,在這種情況下, 分配可以在構造函數體來完成:

class A { 
    B b; // private 
public: 
    A { 
    b = somethingComplicated...; // assigns new value to default constructed B. 
    } 
}; 
+0

+1。這被稱爲「_initialization list_」,因爲它列出了成員的初始值。 – MSalters 2012-07-24 13:09:26

0

您已經創建的b實例在第3行此行是足以讓B的構造函數被調用。如果你有這樣的

class A { 
    private: 
    B *b; 
    public: 
    A() { 
     //instantiate b here? 
    } 
}; 

代碼,然後它將使意義在A's的構造器b

A() 
{ 
    b = new B(); 
} 
+0

但是這將是不好的代碼。不要介意原始指針不應該擁有內存,你應該使用初始化列表而不是構造函數體中的賦值。 – 2012-07-24 13:12:45

0

在3號線,它只是一個B.聲明然而在你的代碼的某個地方,你必須:

A a;

A a(); 

這調用了構造函數A.內部b私有成員已滿或垃圾,因爲在未初始化。你是正確的,你可以或許應該在可能的時候初始化成員變量。有兩種方法可以做到這一點:

A() 
{ 
    b = B(); 
} 

就像你說:

A() : b (B()) 
{ 
} 

第二個版本(初始化列表)會更有效,因爲它直接創建新的B對象裏面b。而第一個版本創建一個臨時的,然後將其移入b。無論如何,您通過傳入參數來初始化成員(對於非內置類型),情況就是如此。我在這種情況下做出了相同的假設,但有人可以澄清。