所有
我有两个文件:
的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'类型不完整且无法定义
我认为是因为我不明白如何使用前瞻声明,所以有人可以告诉我该怎么做吗?
顺便说一下,我知道头文件的方式是这样做的,但我只是想以这种前向声明的方式弄清楚。最好的,
答案 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.h
(include 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()实例化时,或者类型被用于在另一个类中声明成员。普通类声明必须在该点之前完成,并且必须在该点知道类定义,因此必须在同一个翻译单元中包含类定义。
有用的一个例子: 前向声明通常用于规避循环类依赖/包含。如果一个类具有第二类的成员,那么它也具有第一类的成员。当一个包括另一个,另一个包括另一个时,会出现问题。当你只使用前向声明并将实际包含推迟到以后的点时,就不再有循环包含了。