7

我正在尝试在 A 类内部声明和使用 B 类,并在 A 外部定义 B。
我知道这是可能的,因为 Bjarne Stroustrup
在他的“C++ 编程语言”一书中使用了这一点
(例如,第 293 页) String 和 Srep 类)。

所以这是我最小的导致问题的代码

class A{
struct B; // forward declaration
B* c;
A() { c->i; }
};

struct A::B { 
/* 
 * we define struct B like this becuase it
 * was first declared in the namespace A
 */
int i;
};

int main() {
}

此代码在 g++ 中给出以下编译错误:

tst.cpp: In constructor ‘A::A()’:
tst.cpp:5: error: invalid use of undefined type ‘struct A::B’
tst.cpp:3: error: forward declaration of ‘struct A::B’

我试图查看 C++ Faq 和我得到的 closeset 在这里这里,
这些不适用于我的情况。
我也从这里阅读了这篇文章,但这并没有解决我的问题。

gcc 和 MSVC 2005 都给出了编译器错误

4

4 回答 4

15

该表达式c->i取消引用指向的指针,struct A::B因此在程序中此时必须可以看到完整的定义。

最简单的解决方法是制作A非内联的构造函数,并在定义struct A::B.

于 2008-11-21T23:42:37.937 回答
11

在定义结构 B 之后定义 A 的构造函数。

于 2008-11-21T23:44:23.970 回答
7

这是一个很好的例子,说明了为什么要将定义与声明分开。您需要更改事物的顺序,以便在A::A()定义之后定义构造函数struct A::B

class A
{
    struct B;
    B* c;
    A();
};

struct A::B
{
    int i;
};

A::A() { c->i; }

int main()
{
    return 0;
}
于 2008-11-21T23:52:59.303 回答
1

有趣的是,我在 Stroustrup 书中提到的第 293 页('11.12 A String Class')遇到了同样的问题。

印刷书中提供的示例似乎有问题,提供以下方法作为内联,而不是在struct Srep定义之后定义它们

class String {
  // ...
  void check(int i) const { if (i<0 || rep->sz <=i) throw Range(); }
  char read(int i) const { return rep->s[i]; }
  void write(int i, char c) { rep=rep->get_own_copy(); rep->s[i]=c; }
  ...etc...

我google了一下,找到了作者最新的这个String类的实现,可以在这里找到: http ://www2.research.att.com/~bs/string_example.c

他似乎已经修改了它,使这些方法不再是内联的,以避免这个线程中提到的问题。

于 2010-10-19T03:08:22.193 回答