文件之间的转发声明

时间:2013-04-17 16:51:08

标签: c++ forward-declaration

所有

我有两个文件:

的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'类型不完整且无法定义

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

顺便说一下,我知道头文件的方式是这样做的,但我只是想以这种前向声明的方式弄清楚。

最好的,

3 个答案:

答案 0 :(得分:6)

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

可以做的是定义指向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包含在文件中后,您就可以创建&amp;按照你的预期使用它。

答案 1 :(得分:3)

main需要知道类A的大小,并且它具有成员函数disp()。因此,必须能够访问类声明。将其放在文件A.hinclude guards不使用命名空间标准)中,并将其包含在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文件中而不是标题中。

答案 2 :(得分:1)

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

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

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