4

全部:

我有两个文件:

主文件

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

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

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

最好的,

4

3 回答 3

6

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

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

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

    return 0;
}

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

这正是标题的用途!

啊:

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

A.cpp:

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

包含a.h在文件中后,您将能够按预期创建和使用它。

于 2013-04-17T16:54:58.687 回答
3

main需要知道类的大小A,以及它有一个成员函数disp()。为此,必须有权访问类声明。将它放在一个文件中A.h(带有包含保护没有 using namespace std),并将其包含在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

主.cpp:

#include "A.h"

int main() { .... }

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

于 2013-04-17T16:54:02.887 回答
1

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

当您实际上想要使用成员变量或成员函数时,或者当类被自动变量或使用 new() 实例化时,或者类型被用来在另一个类中声明成员时。正常的类声明必须在该点之前完成,并且在该点必须知道类定义,因此必须在同一翻译单元中包含类定义。

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

于 2013-04-17T16:56:52.213 回答