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

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

我有以下问题。我有这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(); }

main.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关键字
  • 保持inline不变,但将方法定义移到.hpp文件中

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

c++ inheritance linker
1个回答
3
投票

你的代码中有一个错误。根据cppreference

内联函数或变量的定义(因为C ++ 17)必须存在于访问它的转换单元中(不一定在访问点之前)。

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

所以你的两种替代方法都可以,因为它们都可以

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

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

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