让我们假设以下代码:
// 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文件。没有一个。
哦,我正在使用MSVC2019。但是我对这段代码是否适用于GCC或其他编译器感兴趣。我必须进行一些测试。
答案 0 :(得分:0)
阅读gudok撰写的精彩文章,如果您不熟悉的话也应该阅读,这让我现在知道发生了什么。
因此,事情是默认情况下内联了Thing :: getOne方法(因为它是在标头中定义和声明的)。内联但未扩展的方法被标记为弱链接。到此为止。