Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;嵌套类转发声明错误_C++_Class_Nested_Declaration_Forward - Fatal编程技术网

C++ C++;嵌套类转发声明错误

C++ C++;嵌套类转发声明错误,c++,class,nested,declaration,forward,C++,Class,Nested,Declaration,Forward,我试图在类a中声明并使用类B 并在A之外定义B。 我知道这是可能的,因为比亚恩·斯特劳斯特鲁普 在《C++程序设计语言》一书中使用这一点 (第293页,例如字符串和Srep类) 因此,这是我的最小代码片段,它会导致问题 class A{ struct B; // forward declaration B* c; A() { c->i; } }; struct A::B { /* * we define struct B like this becuase it * was fi

我试图在类a中声明并使用类B 并在A之外定义B。
我知道这是可能的,因为比亚恩·斯特劳斯特鲁普
在《C++程序设计语言》一书中使用这一点 (第293页,例如字符串和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++常见问题,我得到的是封闭式的,但是
这些不适用于我的情况。
我也是从这里来的,但这并不能解决我的问题


gcc和MSVC 2005都在这方面给出了编译器错误,表达式
c->i
取消引用指向
struct A::B的指针,因此此时必须在程序中看到完整的定义


最简单的解决方法是使
A
的构造函数非内联,并在定义
struct A::B
后为其提供一个主体,在定义struct B之后为A定义构造函数。

这是一个很好的例子,说明了为什么要将定义与声明分开。您需要更改事物的顺序,以便构造函数
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;
}

有趣的是,我在Stroustrup一书中提到的第293页(“11.12a字符串类”)中遇到了同样的问题

印刷书籍中提供的示例似乎有问题,它提供了以下内联方法,而不是在定义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...
类字符串{
// ...
无效检查(int i)常量{if(isz s[i];}
无效写入(inti,charc){rep=rep->get_own_copy();rep->s[i]=c;}
等
我在谷歌上搜索了一下,找到了作者这个字符串类的最新实现,可以在这里找到:


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

构造函数是在声明B之后定义的。它需要在定义B之后定义。更新为将“声明”替换为“定义”。-)或者,在定义结构B之后,使用
inline
关键字将函数定义为inline。