文件之间的转发声明

Forward declaration between files

本文关键字:声明 转发 之间 文件      更新时间:2023-10-16

全部:

我有两个文件:

main.cpp

#include <iostream>
using namespace std;
class A;
int main(){
    A a;
    a.disp();
    return 0;
}

以及A.cpp

#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类的指针:

int main(){
    A *a;
    // a->disp() is still invalid
    return 0;
}

但你将无法用它做任何事情。

这正是标题的作用!

A.h:

class A{
public:
    A(){}
    void disp();
};

A.cpp:

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

在文件中包含a.h之后,您将能够创建&按照你的期望使用它。

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

文件A.h

#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:

#include "A.h"
int main() { .... }

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

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

当您实际想要使用membervariable或memberfunction时,或者当类由自动变量或使用new((实例化时,或者该类型用于声明另一个类中的成员时。正常的类声明必须在这一点之前完成,并且类定义必须在那一点上已知,因此在同一转换单元中必须包含类定义。

一个有用的例子是:正向声明通常用于规避循环类依赖性/包含性。如果一个类有第二类的成员,那么它也有第一类的成员。当一个包含另一个,而另一个包含一个时,问题就会出现。当您只使用正向声明并将实际包含推迟到以后的某个点时,就不再有循环包含了。