【发布时间】:2012-02-09 11:24:19
【问题描述】:
我有一个类,它声明了一个方法但没有实现它。该方法不是虚函数。在相应的 cpp 文件中我没有找到相同方法的定义。类中声明的所有其他方法均已定义。
我编译了代码,它运行良好。我的印象是 cpp 必须强制定义声明的方法。
如果有人可以详细说明,不胜感激。我正在使用 VS2010 的 cl 编译器。
【问题讨论】:
标签: c++ compilation linker
我有一个类,它声明了一个方法但没有实现它。该方法不是虚函数。在相应的 cpp 文件中我没有找到相同方法的定义。类中声明的所有其他方法均已定义。
我编译了代码,它运行良好。我的印象是 cpp 必须强制定义声明的方法。
如果有人可以详细说明,不胜感激。我正在使用 VS2010 的 cl 编译器。
【问题讨论】:
标签: c++ compilation linker
您的代码可以编译,但会出现链接错误。
构建项目的可执行文件涉及两个阶段:
在编译期间,编译器仅通过验证语言语义将源代码转换为目标代码。
在链接期间,链接器实际上查找符号的定义并从多个目标文件(在编译期间创建)创建可执行文件。
编译器分别编译每个翻译单元(.cpp + 头文件)中的源代码,因此它假定定义应该存在于其他一些源文件中。链接器试图找到对函数定义的引用,因此链接器将报告丢失的定义。
请注意,链接器只需要链接您的程序使用的那些符号,
例如:如果您的程序声明了一个函数,但没有提供任何定义,然后在任何地方都不会使用/调用该函数,则链接器不需要嵌入代码来跳转到目标代码所在的地址函数驻留在任何函数调用站点。
在这种情况下,链接器根本不需要查找函数定义。因此代码将编译和链接。
【讨论】:
不需要在特定文件中实现该方法。实际上,在与库链接时,每个方法都有一个文件以减少臃肿是(或曾经)被认为是良好的编程习惯。
这意味着给定一个定义类的头文件(并且可能没有实现),编译器只能假设所有函数都在某个地方实现。只有在系统尝试将所有内容放在一起(链接阶段)时,您才可以明显看出您指的是不存在的东西。
【讨论】:
这是防止分配或复制的常用技术。如果你声明它但没有定义它,如果你尝试使用它就会发生链接错误,即防止人们无意中使用它
【讨论】:
编译器不会抱怨,因为没有语法/编译器错误。 链接器不会抱怨,因为您没有在程序中调用该函数,因此不需要链接。
【讨论】: