2009-12-14 85 views
0

有没有办法在头文件中声明这些类而不间接?声明不带指针的默认参数循环引用?

// Forwards declaration of B 
class B; 

class A 
{ 
public: 
    // Default parameter referring to B. May return its parameter 
    const B& func(const B& b = B()); 
}; 

class B 
{ 
public: 
    // B ctors 
    B() {} 
    B(const B&) {} 

    // B has A as a member 
    A a; 
}; 

的Visual C++ 2008告诉我这件事:

error C2514: 'B' : class has no constructors 

和点B的前向声明( “B类”;),显然不能见下文B的构造函数。 A不能跟随B,因为B包含A作为成员。

如果必须使用间接方式,那么最好的方法是什么?也许在C++ 0x B的A可能是一个unique_ptr成员?或者也许纯粹是为了回避这个问题而增加一个强化班?

回答

7

而不是一个默认参数声明两个重载,一个参考B和一个不参数。在不采用参数的情况下,使用B()来调用另一个,这将起作用,因为可以在定义B之后定义该方法。

... 
    void func(); 
    void func(const B& b); 
}; 

class B... 

void A::func() { func(B()); } 
void A::func(const B&) { } 

更新:

FUNC()返回一个const乙& ......

这可能不是一个好主意。有了这个定义,是这样的:

const B& foo = a.func(); 
foo.bar(); 

会因为B到你有一个参考值将尽快第一个语句是完全破坏导致可怕的“未定义行为”(即崩溃)。通过引用返回除班级成员之外的东西通常是一个糟糕的主意。

如果你真的想这样做,那么我认为你坚持强制调用者明确地通过B(),即没有默认参数。

a.func(B()).bar(); 

(这是为了避免与这样的功能未定义行为的唯一途径。)

当然,你可以只返回一个副本,而不是一个参考,但我相信你有没有这样做的理由那。

根据你在做什么,你可以使用像shared_ptr这样的智能指针代替引用来设置更好的语义,这样就可以有效地忽略对象的生存期。但是,您必须开始小心参考循环。

我不能说出你想要用什么,但你可能想看看Design Patterns看看是否有一个确定的最佳实践。你可能会发现这个小问题是一个不幸选择阶级结构或遏制的症状。

+0

感谢您的回答。这会工作,但我忘了提及 - func()返回一个常量B&,并可能返回它的参数,所以没有参数的版本是没有意义的。然后怎样呢? – AshleysBrain 2009-12-14 00:18:32