有没有办法在没有间接的头文件中声明这些类?
// 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成员?或者也许有一个提升类纯粹是为了回避这个问题?
答案 0 :(得分: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 B& ...
这可能不是一个好主意。有了这个定义,就像:
const B& foo = a.func();
foo.bar();
会导致可怕的“未定义行为”(即崩溃),因为第一个语句完成后,您引用的B
将被销毁。通过引用返回类成员以外的东西通常是一个坏主意。
如果你真的想这样做,那么我认为你不得不强迫调用者明确传入B()
,那就是没有默认参数。
a.func(B()).bar();
(这是避免使用此类函数的未定义行为的唯一方法。)
当然你可以只返回副本而不是引用,但我认为你有理由不这样做。
根据您正在做的事情,您可以使用类似shared_ptr
的智能指针而不是引用来设置更好的语义,这样您就可以有效地忽略对象的生命周期。然而,你必须开始小心参考周期。
我无法分辨您尝试使用此功能的方法,但您可能需要查看一些Design Patterns以查看是否已建立最佳实践。你可能会发现这个小问题是不幸选择阶级结构或遏制的症状。