c++ - 为什么这不会为链接器生成重复的符号?
问题描述
让我们假设以下代码:
// IInterface.h
#pragma once
class IInterface
{
public:
struct Thing
{
// If i uncomment this line, I can see that all object files increase in size.
// char data[10240];
int getOne() { return 1;}
};
// The interface doesn't really matter
};
// Derived1.h
#pragma once
#include "IInterface.h"
class Der1: public IInterface
{
public:
int getOne();
};
// Derived2.h
#pragma once
#include "IInterface.h"
class Der2: public IInterface
{
public:
int getOne();
};
// Derived1.cpp
#include "Derived1.h"
int Derived1::getOne()
{
Thing thing;
return thing.getOne();
}
// Derived2.cpp
#include "Derived2.h"
int Derived2::getOne()
{
Thing thing;
return thing.getOne();
}
// main.cpp
// Not really needed I guess?
#include "Derived1.h"
#include "Derived2.h"
int main(int argc, char* argv[])
{
Der1 der1;
Der2 der2;
return der1.getOne() - der2.getOne();
}
现在我不知道如何用语言表达这个问题,但我开始了。
为什么方法 IInterface::Thing::getOne 不会生成链接器错误,因为它在不同的翻译单元中有多个版本?
如果我制作了一个版本,其中 getOne 只是在 IInterface.h 中声明和定义的全局函数,那将产生链接器错误。
我知道我可以将结构移动到单独的 .cpp 文件,但由于它是 IInterface 并且我使用的是 C++17,因此我不需要 .cpp 文件。没有一个。
哦,我在 MSVC 2019 上。但我很感兴趣这段代码是否适用于 GCC 或其他编译器。我将不得不进行一些测试。
解决方案
阅读gudok的优秀文章,如果你不熟悉,你也应该阅读,让我现在明白发生了什么。
所以问题是 Thing::getOne 方法默认是内联的(因为它是在标题中定义和声明的)。内联但未扩展的方法被标记为弱链接。这就是结束。
推荐阅读
- python - 如何确定存储在文件中的最大拼字游戏分数?
- php - 如何使用 PHP 的 include 连接到数据库
- javascript - 在javascript中解构时获取父母和孩子
- node.js - IIS & HapiJS 错误:尝试提供静态文件时出现 404
- java - java中如何通过接口指定类类型
- scala - 如何向另一个还没有准备好的参与者请求数据?
- leaflet - 使用图层控件时不显示图层的开始地图
- c - 在 C 中创建一个网格形状(为什么要创建一个额外的线?)
- c# - C# - 属性的类型,以及何时使用一种而不是另一种
- ms-access - 从 MS Access 复选框获取值