c++ - 类具有内部定义的函数时的链接错误

标签 c++ linker inline

f1.cpp文件包含两个简单类的代码。 A类具有在内部定义的print()函数,B类具有在外部定义的函数。

class A{
public:
    void print(){}
};

class B{
public:
    void print();
};

void B::print(){
}
f1.cpp将生成f1.libf2.cpp包含两个类的头和main()函数(它将与f1.lib链接以创建f2.exe):
class A{
public:
    void print();
};

class B{
public:
    void print();
};

int main(){
    A a;
    a.print();

    B b;
    b.print();
}
当我在Visual Studio 2019中进行编译时,仅出现类A的链接错误:
error LNK2001: unresolved external symbol "public: void __thiscall A::print(void)" (?print@A@@QAEXXZ)
fatal error LNK1120: 1 unresolved externals
似乎A::print函数在lib中没有作为符号出现。
最初,我认为这是因为内部函数定义默认情况下变为“内联”。但是我尝试在其前面添加__declspec(noinline)属性,但仍然无法正常工作。
您知道为什么没有该符号吗?

最佳答案

f2.cpp重新声明了AB,为什么?
两个文件中的B声明都匹配,这是可以的,链接器会将它们与B::print()中的外部f1.cpp定义匹配。
但是两个文件中的A声明都不匹配,这不正确,并且是未定义的行为。 A中的f1.cpp具有自己独特的print()内联定义,但是A中的f2.cpp具有print()的非内联声明,并且没有匹配的外部定义供链接器查找,因此出错。f2.cpp根本不应重新声明AB。请改用头文件,例如:

// f1.h

#ifndef F1_H
#define F1_H

class A{
public:
    void print() { ... }
    // or: void print();
};

#endif
// f1.cpp (only if A::print() is not inline)

#include "f1.h"

void A::print() {
    ...
}
// f2.h

#ifndef F2_H
#define F2_H

class B{
public:
    void print();
};

#endif
//f2.cpp

#include "f1.h"
#include "f2.h"

void B::print() {
    ...
}

int main() {
    A a;
    a.print();

    B b;
    b.print();
}
或者:
// f1.h

#ifndef F1_H
#define F1_H

class A{
public:
    void print() { ... }
    // or: void print();
};

class B{
public:
    void print();
};

#endif
//f2.cpp

#include "f1.h"

// uncomment if A::print() is not inline...
/*
void A::print() {
    ...
}
*/

void B::print() {
    ...
}

int main() {
    A a;
    a.print();

    B b;
    b.print();
}

关于c++ - 类具有内部定义的函数时的链接错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64670427/

相关文章:

c++ - 为什么我们需要在 Windows C++ 中链接 kernel32.dll、user32.dll 等...?

带有非标准框架 ld : warning: directory not found for option -F 的 Xcode 警告

css - 带有 <a> 的内联 img 在 IE 中导致奇怪的问题

c - Perl:如何将所有内联 C 代码放入单独的文件中?

c# - 从多字节编码到 Unicode 的转换

c++ - 将 C++ vector 作为成员放入使用内存池的类中

用于匹配 Windows 和 Posix 系统的日期时间的 C++ 正则表达式模式

c++ - 为什么构建同一个项目会为每个开发人员生成不同的 EXE 文件

javascript - 使用内联 Javascript 有什么优势?

c++ - 当我读取一个大小为 17 mb 的 100 万个 url 的文件时,我的程序占用了 163 mb 的大小