编译包含标头中声明的函数的源文件

问题描述 投票:0回答:3

假设有一个源文件un2.cpp

----un2.cpp----

class employee;
void employee::setname(string s)
{
.....(some  code)
}

employee 类在 un2.h 中定义,其中声明了 setname()。 现在,当我尝试通过“cc -c un2.cpp -o un2.o”编译un2.cpp时,我收到一条错误消息

 un2.cpp:3:16: error: invalid use of incomplete type ‘struct employee’
 un2.cpp:1:7: error: forward declaration of ‘struct employee’

为什么编译器不直接将employee作为外部符号(就像它采用先前声明但未定义的符号一样)并编译un2.cpp文件。

编译普通的未定义符号和未定义类有什么区别吗? 也有人可以告诉我(如果可能的话),如何转发声明一个类并定义其中的符号?

c++ class g++ forward-declaration
3个回答
3
投票

external 用于链接器,在编译代码时不会为您提供帮助,因为编译器仅通过编写前向声明并不知道您的类声明。

相反,您需要在 un2.cpp 文件中包含带有声明的标头才能进行编译。


2
投票

您尚未将该文件包含在类的声明中。前向声明在这里没有帮助,因为编译器不知道该类是否包含这样的方法。

包含头文件,错误就会消失。


2
投票

重点是,类不是用符号表示的,但必须知道完整的类结构才能生成代码。首先,编译器需要类定义来检查类

employee
是否确实包含一个名为
setname
的成员函数,该函数接受
string
并返回
void
(如果不存在,编译器必须返回错误)。此外,您需要在函数内访问类的其他成员(调用其他成员函数或访问数据成员),因此您需要这些声明,它们是类定义的一部分。在链接时,类名完全消失了(除了调试信息,以及作为成员函数和虚表符号的一部分)。

一般来说,在编写头文件的实现文件时,应该将头文件包含在实现文件中。这将确保您拥有定义在那里声明的所有内容所需的一切,此外还测试头文件,前提是您将其作为实现文件中的第一件事。

© www.soinside.com 2019 - 2024. All rights reserved.