【问题标题】:Method declared in Class but not defined在 Class 中声明但未定义的方法
【发布时间】:2012-02-09 11:24:19
【问题描述】:

我有一个类,它声明了一个方法但没有实现它。该方法不是虚函数。在相应的 cpp 文件中我没有找到相同方法的定义。类中声明的所有其他方法均已定义。

我编译了代码,它运行良好。我的印象是 cpp 必须强制定义声明的方法。

如果有人可以详细说明,不胜感激。我正在使用 VS2010 的 cl 编译器。

【问题讨论】:

    标签: c++ compilation linker


    【解决方案1】:

    您的代码可以编译,但会出现链接错误。

    构建项目的可执行文件涉及两个阶段:

    • 编译
    • 链接

    编译期间,编译器仅通过验证语言语义将源代码转换为目标代码。
    链接期间,链接器实际上查找符号的定义并从多个目标文件(在编译期间创建)创建可执行文件。

    编译器分别编译每个翻译单元(.cpp + 头文件)中的源代码,因此它假定定义应该存在于其他一些源文件中。链接器试图找到对函数定义的引用,因此链接器将报告丢失的定义。

    请注意,链接器只需要链接您的程序使用的那些符号,
    例如:如果您的程序声明了一个函数,但没有提供任何定义,然后在任何地方都不会使用/调用该函数,则链接器不需要嵌入代码来跳转到目标代码所在的地址函数驻留在任何函数调用站点。
    在这种情况下,链接器根本不需要查找函数定义。因此代码将编译和链接。

    【讨论】:

    • 恕我直言,只有在缺少定义的函数在某处被显式/隐式使用/调用时才会发生链接错误。
    • 我没有收到任何编译或链接错误。只是补充一下,我没有在任何地方使用该功能。代码编译并链接到 .lib 文件中。
    • @akrohit 如上所述,如果你没有在任何地方使用该函数,则无需定义它,不会出现编译错误和链接错误。
    • @akrohit:为了清楚起见,我更新了答案,也许我之前不够清楚并假设了一些方面。
    【解决方案2】:

    不需要在特定文件中实现该方法。实际上,在与库链接时,每个方法都有一个文件以减少臃肿是(或曾经)被认为是良好的编程习惯。

    这意味着给定一个定义类的头文件(并且可能没有实现),编译器只能假设所有函数都在某个地方实现。只有在系统尝试将所有内容放在一起(链接阶段)时,您才可以明显看出您指的是不存在的东西。

    【讨论】:

    • 不是真的。它可以减少臃肿和令人惊讶的链接问题。一些现代编译器通过将每个函数都放在单独的对象部分中来使这一点变得不必要,但大多数都没有。
    • 我仔细检查过,在任何其他文件中也找不到我上面所说的方法的定义。
    • @RonaldMcBean - 这就是它在 Linux 和 libc 中(主要)是如何完成的。如果您查看源代码,您会看到每个 POSIX/Linux 内核函数的单独实现文件(主要针对所有函数。)
    【解决方案3】:

    这是防止分配或复制的常用技术。如果你声明它但没有定义它,如果你尝试使用它就会发生链接错误,即防止人们无意中使用它

    【讨论】:

      【解决方案4】:

      编译器不会抱怨,因为没有语法/编译器错误。 链接器不会抱怨,因为您没有在程序中调用该函数,因此不需要链接。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-04
        • 1970-01-01
        • 2014-10-12
        相关资源
        最近更新 更多