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 的前向声明(“class B;”),显然在下面看不到 B 的构造函数。A 不能跟随 B,因为 B 包含 A 作为成员。

如果必须使用间接,最好的方法是什么?也许在 C++0x B 中的 A 可能是一个 unique_ptr 成员?或者,也许有一个提升类纯粹是为了回避这个问题?

4

1 回答 1

7

代替默认参数声明两个重载,一个接受B引用,一个不接受参数。在不带参数的一个中,用 调用另一个B(),这将起作用,因为该方法可以在定义后B定义。

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

class B...

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

更新:

func() 返回一个常量 B&...

这可能不是一个好主意。使用该定义,类似于:

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

会导致可怕的“未定义行为”(即崩溃),因为B一旦第一个语句完成,您引用的 将被销毁。通过引用返回类成员以外的东西通常是一个坏主意。

如果你真的想这样做,那么我认为你坚持强制调用者显式传递B(),即没有默认参数。

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

(这是使用此类函数避免未定义行为的唯一方法。)

当然,您可以只返回一份副本而不是参考,但我认为您有理由不这样做。

根据您所做的事情,您可以使用智能指针shared_ptr而不是引用来设置更好的语义,这样您就可以有效地忽略对象的生命周期。但是,您必须开始注意参考周期。

我不知道你想用它做什么,但你可能想看看一些设计模式,看看是否有一个既定的最佳实践。你可能会发现这个小问题是一个不幸的类结构或包含选择的症状。

于 2009-12-14T00:07:07.143 回答