类的前向声明似乎在C++中不起作用

Lop*_*per 13 c++ compilation header declaration forward-declaration

以下代码在VC++ 6中编译.我不明白为什么我得到C2079: 'b' uses undefined class 'B'以下代码的编译错误.

B类来源

#include "B.h"

void B::SomeFunction()
{
}
Run Code Online (Sandbox Code Playgroud)

B级标题

#include "A.h"

struct A;

class B
{
    public:
        A a;
        void SomeFunction();
};
Run Code Online (Sandbox Code Playgroud)

struct A Header

#include "B.h"

class B;

struct A
{
    B b;
};
Run Code Online (Sandbox Code Playgroud)

如果我将B类标题更改为以下内容,则不会出现错误.但标题声明不会在顶部!

具有奇怪标头声明的B类标头

struct A;

class B
{
     public:
        A a;
        void SomeFunction();
};

#include "A.h"
Run Code Online (Sandbox Code Playgroud)

Mat*_*vis 18

为了定义类或结构,编译器必须知道类的每个成员变量有多大.前瞻性声明不会这样做.我只见过它用于指针和(不太经常)引用.

除此之外,你在这里想做的事情是无法做到的.你不能有一个包含A类对象包含了另一个类B的对象类答:您的可以然而,有A类包含一个指向 B类包含一个对象类A的

B.cpp

#include "B.h"

void B::SomeFunction()
{
}
Run Code Online (Sandbox Code Playgroud)

BH

#ifndef __B_h__  // idempotence - keep header from being included multiple times
#define __B_h__
#include "A.h"

class B
{
public:
    A a;
    void SomeFunction();
};

#endif // __B_h__
Run Code Online (Sandbox Code Playgroud)

#ifndef __A_h__  // idempotence - keep header from being included multiple times
#define __A_h__
#include "B.h"

class B; // forward declaration

struct A
{
    B *b;  // use a pointer here, not an object
};

#endif // __A_h__
Run Code Online (Sandbox Code Playgroud)

两点.首先,请确保使用某种形式的幂等性来防止每个编译单元多次包含标头.其次,要理解在C++中,类和结构之间的唯一区别是默认的可见性级别 - 默认情况下,类使用私有可见性,而默认情况下结构使用公共可见性.以下定义在C++中在功能上是等效的.

class MyClass
{
public: // classes use private visibility by default
    int i;
    MyClass() : i(13) { }
};

struct MyStruct
{
    int i;
    MyStruct() : i(13) { }
};
Run Code Online (Sandbox Code Playgroud)

  • 双下划线是为编译器保留的.使用不同的命名约定. (5认同)

Tad*_*pec 5

前向声明,例如

struct A;
Run Code Online (Sandbox Code Playgroud)

或者

class A;
Run Code Online (Sandbox Code Playgroud)

将 A 作为不完整类型引入,并且在到达类型定义末尾之前它一直保持不完整状态。对于不完整的类型,有些事情可以做,有些事情不能做。你可以

  1. 声明“指向 A 的指针”和“对 A 的引用”类型的变量(或成员)
  2. 声明采用 A 类型参数或返回 A 类型的函数

你不能

  1. 声明类型 A 的变量(或成员)
  2. 取消引用 A 的指针或访问 A 引用的任何成员
  3. 定义 A 的子类。

在您的代码中,您尝试声明不完整类型的结构成员。这是非法的。仅允许指针和引用。