关于c ++:文件之间的转发声明

 2020-02-14 

Forward declaration between files

所有:

我有两个文件:

main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>

using namespace std;

class A;

int main(){
    A a;
    a.disp();

    return 0;
}


丙型肝炎

1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;

class A{

    public:
    A(){}
    void disp(){ cout<<"this is A disp()"<<endl;}
};

我不知道为什么当我编译这两个文件时,它告诉我:

main.cpp:在" int main()"函数中:
main.cpp:8:4:错误:聚合" A a"类型不完整,无法定义

我认为是因为我不了解如何使用前向声明,所以有人可以告诉我该怎么做吗?

顺便说一句,我知道执行此操作的头文件方式,但是我只想找出这种向前声明的方式。

最好,


由于您只是将其声明为一个类(即,您没有告诉编译器该类包含什么),因此它无法为其创建内存(它不知道它需要多大)。

您可以做的是定义指向A类的指针:

1
2
3
4
5
6
int main(){
    A *a;
    // a->disp() is still invalid

    return 0;
}

但您将无法执行任何操作。

这正是标题的用途!

啊:

1
2
3
4
5
class A{
public:
    A(){}
    void disp();
};

A.cpp:

1
2
3
4
#include"A.h"
void A::disp(){
    cout<<"this is A disp()"<<endl;
}

在文件中包含A.h之后,您将可以按期望的方式创建和使用它。


main需要知道类A的大小,并且它具有成员函数disp()。因此,必须有权访问类声明。将其放在文件A.h中(带有包含保护并且不使用命名空间std),并将其包含在main.cpp中。

文件A.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef A_H_
#define A_H_

#include <iostream>

class A
{
    public:
    A(){}
    void disp() const {
      std::cout<<"this is A disp()"<<std::endl;
    }
};

#endif

main.cpp:

1
2
3
#include"A.h"

int main() { .... }

请注意,您可以决定将void A::disp()的实现放在A.cpp文件中,而不是在标头中。


当您仅在另一个类声明中使用指向一个类的指针时,仅需要一个前向声明。这意味着此时仅知道类的名称,而不知道其成员的定义或其大小。类型不完整。

当您实际上要使用membervariable或memberfunction时,或者通过自动变量或使用new()实例化该类时,或者使用该类型来声明另一个类中的成员时。普通的类声明必须在此之前完成,并且类定义必须在该点之前为人所知,因此必须在同一翻译单元中包含类定义。

一个有用的示例:
前向声明通常用于规避循环类的依赖/包含。如果一个班级有第二类的成员,那么该班级也有第一类的成员。当一个包含另一个,而另一个包含一个时,就会出现问题。当您仅使用前向声明并将实际包含推迟到以后时,就不再有循环包含。