c++ - 在另一个项目中包含继承类时出现抽象类的链接器错误

标签 c++ inheritance abstract-class

如果我有一个抽象类

像这样:

#pragma once
#include <string>

class BaseObject
{
public:
    virtual std::string to_string() = 0;
};

一些类扩展了这个类。

#pragma once
#include "baseobject.h"

class Point : BaseObject
{
public:
    Point() {}
    ~Point() {}
    Point(float _x, float _y) : x(_x), y(_y) {}

    std::string to_string();

    float x, y;
};

在同一个项目中,我可以实现 to_string 的功能在派生类的 cpp 文件中,但是当我想在同一解决方案的另一个项目中使用此类时,出现链接器错误

error LNK2001: unresolved external symbol "public: virtual class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl Point::to_string(void)" (?to_string@Point@@UEAA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@XZ) 1>path\to\CircleHT_Test.exe : fatal error LNK1120: 1 unresolved externals

一旦我将实现移动到头文件中,一切都很好。为什么是这样?我应该始终在派生类的 header 中实现纯虚函数吗?

最佳答案

Within the same project I can have the function implementation of to_string in the cpp file of the extension class but when I want to use this class in another project in the same solution I get a linker error.

Point::to_string 的实现源代码在某个实现文件中,大概叫做point.cpp。该文件包含在项目的源文件列表中。因此,当您构建项目时,它会被编译成一个 point.obj 文件,其中包含该函数的二进制代码。该文件最终由链接器用来生成可执行程序。

当您构建不同的项目时,point.cpp 不在源文件列表中。您在某处包含 point.h 的事实无关紧要。将类分成*.cpp*.h 文件是只是一个非常普遍的约定。如果你只是包含了*.h文件,并没有确保相应的*.cpp文件被编译成*.obj文件,那么结果正是您在这里遇到的情况:没有创建 point.obj,因此链接器正确地提示缺少定义。

最简洁的解决方案是将第一个项目或第一个项目的一部分转换为一个库项目,该项目被构建到一个*.lib 文件中。然后应将该 *.lib 文件添加到需要它的每个应用程序项目的链接器依赖项中。


once I move the implementation to the header file it's all good. Why is this?

因为在那种情况下,函数的实现是内联的,并且包含头文件的其他项目中的每个 *.cpp 文件都会获取它。


最后,请注意这个答案在某种程度上特定于 Visual Studio/Visual C++,尽管构建过程的基本思想通常对于每个工具集都是相同的。

关于c++ - 在另一个项目中包含继承类时出现抽象类的链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42887223/

相关文章:

c++ - 写入 vector 数组时,fwrite 因参数无效而失败

c++ - ncurses可用于Windows吗?

c# - 如果类继承多次可以慢一些吗?

java - opencsv不导出父类的属性

oop - 在哪里可以找到有关 OOP 的深入信息?

c++ - 跟踪注入(inject)过程中的 HDC

C++ 将格式化字符串转换为流

c# - 在 .Net Hierarchy 中隐藏方法

python - 我们可以从没有实例化的类中调用方法吗

java - 如何从父类(super class)对象调用子类方法