C++ 继承 - 无法在 cpp 文件中定义方法

标签 c++ inheritance linker

我有以下问题。我有这 3 个文件(我做了一个简化的例子,但错误是一样的):

foo.hpp

#pragma once
#include <iostream>

class foo
{
protected:
    virtual void bar() const noexcept = 0;

public:
    foo() = default;
    virtual void callbar() = 0;
};

class baz : public foo
{
protected:
    void bar() const noexcept override;

public:
    void callbar();
};

foo.cpp

#include "foo.hpp"

inline void baz::bar() const noexcept { std::cout << "baz::bar()" << '\n'; }

inline void baz::callbar() { bar(); }

主要.cpp

#include "foo.hpp"

auto main() -> int
{
    baz b;
    b.callbar();
}

编译器(我猜实际上是链接器)给我以下错误:

foo.cpp
main.cpp
Generating Code...
Microsoft (R) Incremental Linker Version 14.15.26729.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:foo.exe
foo.obj
main.obj
main.obj : error LNK2001: unresolved external symbol "protected: virtual void __cdecl baz::bar(void)const " (?bar@baz@@MEBAXXZ)
main.obj : error LNK2019: unresolved external symbol "public: virtual void __cdecl baz::callbar(void)" (?callbar@baz@@UEAAXXZ) referenced in function main
foo.exe : fatal error LNK1120: 2 unresolved externals

现在我通过做以下两件事中的任何一件来解决这个问题:

  • 删除内联关键字
  • 保持 inline 不变,但将方法定义移动到 .hpp 文件

如果我做其中一件事情,一切都会正常。但我的问题是:为什么?在我的真实代码中,我真的希望编译器内联方法调用,而且我希望它们在 .cpp 文件中定义,以使我的 .hpp 文件更清晰。有解决办法吗?

最佳答案

您的代码中有错误。根据cppreference

The definition of an inline function or variable (since C++17) must be present in the translation unit where it is accessed (not necessarily before the point of access).

显然,当您将定义放在 .cpp 文件中并从其他翻译单元调用这些函数时,这个条件是不满足的。

所以你的两种替代方法都有效,因为它们要么

  • 完全删除此条件(当您删除内联说明符时)
  • 使定义可见

最后但并非最不重要的一点——C++ inline 说明符与函数内联无关。还有其他依赖于编译器的方法来请求实际的内联,即各种编译器中的 __forceinline

关于C++ 继承 - 无法在 cpp 文件中定义方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55615555/

相关文章:

c++ - 从根高效计算多项式系数

c++ - 如何在 C++ 中为任意数量的字符串连接编写可变参数函数

c++ - Eclipse 强制将 -k 添加到 C++ 构建命令参数

Java:用类型方法覆盖泛型方法?

linker - 无法打开文件 atls.lib

c++ - C++20中模板类的概念

c++ - 调用虚拟方法而不是派生方法

java - 扩展 Java 类并强制现有库使用扩展类

c++ - GraphicsMagick.NET 缺少 CORE_RL_bzlib_.lib 文件,C++ 链接器错误?

c++ - 运行时链接错误 : The procedure entry point glewInit@0 could not be located