c++ - 声明没有指针的默认参数循环引用?

标签 c++ header definition circular-reference

有没有什么方法可以在头文件中声明这些类而无需间接访问?

// 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 成员?或者也许有一个提升类纯粹是为了回避这个问题?

最佳答案

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

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

class B...

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

更新:

func() returns a const B&...

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

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

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

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

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

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

当然,您可以只返回拷贝而不是引用,但我认为您有不这样做的理由。

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

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

关于c++ - 声明没有指针的默认参数循环引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1898284/

相关文章:

c++ - C++中对象的定义

c - int arr; 的定义有什么区别吗?和 int arr[1];

c++ - 如何在 MPI 中 sleep

c++ - 线程间共享类的静态数据

c - 声明和定义问题

html - 如何通过Content-Security-Policy检查哪些内容被阻止了?

c++ - 在另一个头文件 C++ 中创建一个类的实例

c++ - 类无法访问其自己的私有(private)静态 constexpr 方法 - Clang 错误?

c++ - 运算符重载 - 内联非成员函数

jquery mobile固定(始终在顶部)标题