2010-03-20 36 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,则会出现未定义的行为。

相关问题