C++ 使用未定义的类/类型不完整

C++ 使用未定义的类/类型不完整,c++,C++,为什么不编译?我的印象是,如果您声明类的原型,那么它们的声明顺序并不重要。然而,这不起作用。在visual studio中,它为我提供: class a; class b; class a { b c; }; class b { }; error C2079: 'a::c' uses undefined class 'b' 在g++中,它给了我: class a; class b; class a { b c; }; class b { }; error C2079

为什么不编译?我的印象是,如果您声明类的原型,那么它们的声明顺序并不重要。然而,这不起作用。在visual studio中,它为我提供:

class a;
class b;

class a {
    b c;
};

class b {
};
error C2079: 'a::c' uses undefined class 'b'
在g++中,它给了我:

class a;
class b;

class a {
    b c;
};

class b {
};
error C2079: 'a::c' uses undefined class 'b'

我做错了什么?

a
使用
b
时,它已经声明(因为您在它上面写了
类;
),但没有定义(定义在
a
下面)。“不完整类型”指已声明但未定义的类型。

a
使用
b
时,该类型已声明(因为您在其上方编写了
b类;
),但未定义(定义在
a
下方)。“不完整类型”指已声明但未定义的类型。

a
使用
b
时,该类型已声明(因为您在其上方编写了
b类;
),但未定义(定义在
a
下方)。“不完整类型”指已声明但未定义的类型。

a
使用
b
时,该类型已声明(因为您在其上方编写了
b类;
),但未定义(定义在
a
下方)。“不完整类型”表示类型已声明但未定义。

当编译器看到

error: field 'c' has incomplete type
它知道
b
存在,但不知道它是什么(因此,它不知道需要多少空间,因此它不知道如何构建
a

但是,您可以在
b
上使用指针:

class a {
  b c;
};

编辑:

这意味着您将无法在定义a
b
之前对其进行操作。例如:你做不到:

class a {
  b* c;
};
在a.cc中

class b; //Say it exists. Don't say what it looks like

class a {
  b* c;
  void f();
};
当编译器看到

error: field 'c' has incomplete type
它知道
b
存在,但不知道它是什么(因此,它不知道需要多少空间,因此它不知道如何构建
a

但是,您可以在
b
上使用指针:

class a {
  b c;
};

编辑:

这意味着您将无法在定义a
b
之前对其进行操作。例如:你做不到:

class a {
  b* c;
};
在a.cc中

class b; //Say it exists. Don't say what it looks like

class a {
  b* c;
  void f();
};
当编译器看到

error: field 'c' has incomplete type
它知道
b
存在,但不知道它是什么(因此,它不知道需要多少空间,因此它不知道如何构建
a

但是,您可以在
b
上使用指针:

class a {
  b c;
};

编辑:

这意味着您将无法在定义a
b
之前对其进行操作。例如:你做不到:

class a {
  b* c;
};
在a.cc中

class b; //Say it exists. Don't say what it looks like

class a {
  b* c;
  void f();
};
当编译器看到

error: field 'c' has incomplete type
它知道
b
存在,但不知道它是什么(因此,它不知道需要多少空间,因此它不知道如何构建
a

但是,您可以在
b
上使用指针:

class a {
  b c;
};

编辑:

这意味着您将无法在定义a
b
之前对其进行操作。例如:你做不到:

class a {
  b* c;
};
在a.cc中

class b; //Say it exists. Don't say what it looks like

class a {
  b* c;
  void f();
};

在中定义什么顺序类并不重要。定义必须在按值使用之前可用。如果
c
b*
(指针)Oli,它可能会像您预期的那样工作,这里它字面上说“任何顺序都可以”。那么原型的目的是什么呢?特洛伊史崔恩,好吧,我试过了,你是对的。为什么呢?如果我想要它的一个实例,而不是指针呢?在这个答案中,所有的类都是原型,所以定义的顺序并不重要。但是,这些定义没有显示任何内容。您不能拥有尚未定义的类的成员;但是,您可以有一个指向未定义类的指针成员。请参阅链接问题的下一个答案。中定义的顺序类并不重要。定义必须在按值使用之前可用。如果
c
b*
(指针)Oli,它可能会像您预期的那样工作,这里它字面上说“任何顺序都可以”。那么原型的目的是什么呢?特洛伊史崔恩,好吧,我试过了,你是对的。为什么呢?如果我想要它的一个实例,而不是指针呢?在这个答案中,所有的类都是原型,所以定义的顺序并不重要。但是,这些定义没有显示任何内容。您不能拥有尚未定义的类的成员;但是,您可以有一个指向未定义类的指针成员。请参阅链接问题的下一个答案。中定义的顺序类并不重要。定义必须在按值使用之前可用。如果
c
b*
(指针)Oli,它可能会像您预期的那样工作,这里它字面上说“任何顺序都可以”。那么原型的目的是什么呢?特洛伊史崔恩,好吧,我试过了,你是对的。为什么呢?如果我想要它的一个实例,而不是指针呢?在这个答案中,所有的类都是原型,所以定义的顺序并不重要。但是,这些定义没有显示任何内容。您不能拥有尚未定义的类的成员;但是,您可以有一个指向未定义类的指针成员。请参阅链接问题的下一个答案。中定义的顺序类并不重要。定义必须在按值使用之前可用。如果
c
b*
(指针)Oli,它可能会像您预期的那样工作,这里它字面上说“任何顺序都可以”。那么原型的目的是什么呢?特洛伊史崔恩,好吧,我试过了,你是对的。为什么呢?如果我想要它的一个实例,而不是指针呢?在这个答案中,所有的类都是原型,所以定义的顺序并不重要。但是,这些定义没有显示任何内容。您不能拥有尚未定义的类的成员;但是,您可以有一个指向未定义类的指针成员。请参阅链接问题的下一个答案。好的,这是一个很好的答案。这是有道理的。所以这意味着没有办法有一个ins