2010-03-20 38 views
3
Class A 
{ 
    A(B& b) : mb(b) 
    { 
    // I will not access anything from B here 
    } 

    B& mb; 
}; 


Class B 
{ 
B(): a(*this) 
{} 

A a; 
} 

我遇到過這種情況可能是次,包含的對象需要使用容器功能。在包含對象中引用容器對象似乎是實現此目的的最佳方法。當然,我可以用一個指針來做到這一點,這樣我可以有一個setter setB(B* b) {mb = b;},我可以在以後確定B被初始化後調用,但我更願意使用引用來實現這一點,這意味着我需要在初始化它構造函數,因此問題。可以在以下示例中通過* this構造函數

+0

我總是好奇的使用情況下,這樣的緊耦合不在乎給予幾個例子? – 2010-03-20 19:56:52

+0

@dribeas:我使用這個,如果我有一個類,我可以明確地將它的職責分解成不同的任務,然後爲每個任務分配助手類,同時允許從「擁有」類訪問所需的數據。就我個人而言,我會讓'A'爲'B'的嵌套私人類來顯示所有者/擁有的關係。 – Troubadour 2010-03-20 20:20:06

回答

1

從標準的適當的報價是:

§3.8[basic.life]/6

類似地,對象的生存期已經開始但在此之前存儲在此之後,對象將佔用已經被分配,或者在對象的生命週期結束之後並且在重新使用或釋放​​該對象佔用的存儲之前,可以使用引用原始對象的任何左值,但是僅以有限的方式使用。這樣一個左值指的是分配的存儲(3.7.3.2),並且使用不依賴於它的值的左值的屬性是明確的。如果將左值到右值轉換(4.1)應用於這樣的左值,則程序具有未定義的行爲;如果要是原來的對象將是或者是一個非POD類類型的,該計劃已未定義行爲:

— the lvalue is used to access a non-static data member or call a non-static member function of the object, or 
— the lvalue is implicitly converted (4.10) to a reference to a base class type, or 
— the lvalue is used as the operand of a static_cast(5.2.9) (except when the conversion is ultimately to char& or unsigned char&), or 
— the lvalue is used as the operand of a dynamic_cast(5.2.7) or as the operand oftypeid. 
+0

@dribeas完美。謝謝。 – Nikhil 2010-03-20 22:16:25

9

由於您只是初始化對B的引用,所以這應該是很好的 - 在B的構造函數運行它的內存位置時,它已經被設置。

請記住,您不能從A的構造函數中安全地調用B中的任何方法,因爲B尚未完成構造。

1

這取決於你在A構造函數中做什麼。

直到構造函數返回時,B對象才被完全構造。此外,在您輸入B構造函數的主體之前,B對象內的對象可能未完全構建。例如:

class B 
{ 
    A a; 
    std::string str; 

public: 
    B() : a(*this) 
    { 
    } 
}; 

那個A::A被調用的時候,str尚未建立。如果您嘗試在A::A範圍內(直接或間接)使用str,則會出現未定義的行爲。

相關問題