gpt4 book ai didi

c++ - 将结构向前声明为类时出现 Visual C++ 2015 链接器错误

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:14 25 4
gpt4 key购买 nike

我有以下代码(涉及多个文件)...

//--- SomeInterface.h
struct SomeInterface
{
virtual void foo() = 0;
virtual ~SomeInterface(){}
};

//--- SomeInterfaceUser.h
#include <memory> //shared_ptr

class SomeInterface;
//NOTE: struct SomeInterface... causes linker error to go away...

class SomeInterfaceUser
{
public:
explicit SomeInterfaceUser(std::shared_ptr<SomeInterface> s);
};

//SomeInterfaceUser.cpp
#include "SomeInterfaceUser.h"
#include "SomeInterface.h"
SomeInterfaceUser::SomeInterfaceUser(std::shared_ptr<SomeInterface> s)
{
}

//SomerInterfaceUserInstantiator.cpp
#include "SomeInterfaceUser.h"
#include "SomeInterfaceImpl.h"

struct SomeInterfaceImpl : SomeInterface
{
virtual void foo(){}
};

void test()
{
SomeInterfaceUser x{std::make_shared<SomeInterfaceImpl>()};
}

使用 Visual C++ 编译器时,出现链接器错误 (LNK2019)。使用 GCC 4.8.4 情况并非如此。将前向声明 class SomeInterface 更改为 struct SomeInterface 会使链接器错误消失。我一直认为应该能够互换使用类/结构? SomeInterfaceUser 的接口(interface)不应该取决于 SomeInterface 是定义为类还是结构,不是吗?

这是 Visual C++ 错误吗?我找不到任何与之相关的东西。我怀疑结构被用作模板参数这一事实与它有关。

感谢您的帮助。

最佳答案

我刚刚在 VC++ 2010 和 VC++ 2017 中遇到了同样的问题,经过一些测试后我发现问题出在编译器内部给结构和类的符号名称上。

这里有一个包含三个文件的最小示例:

main.cpp

#include "bar.h"
struct Foo {};

int main() {
Foo foo;
bar(&foo);
return 0;
}

bar.h

class Foo;
void bar(Foo* f);

bar.cpp

#include "bar.h"

void bar(Foo* foo) {}

编译项目时出现以下错误和警告:

warning C4099: 'Foo': type name first seen using 'class' now seen using 'struct'

see declaration of 'Foo'

error LNK2019: unresolved external symbol "void __cdecl bar(struct Foo *)" (?bar@@YAXPAUFoo@@@Z) referenced in function _main

fatal error LNK1120: 1 unresolved externals

现在,我交换了 structclass 声明,所以 main.cppbar.h 是现在:

main.cpp

#include "bar.h"
class Foo {};

int main() {
Foo foo;
bar(&foo);
return 0;
}

bar.h

struct Foo;
void bar(Foo* f);

不出所料,错误仍然弹出:

error LNK2019: unresolved external symbol "void __cdecl bar(class Foo *)" (?bar@@YAXPAVFoo@@@Z) referenced in function _main

但是,这是有趣的部分,请注意预期函数的符号(main() 中使用的符号)在每种情况下都不同:

  • ?bar@@YAXPAUFoo@@@Z(当参数是一个struct时)

  • ?bar@@YAXPAVFoo@@@Z(当参数是一个时)


结论

如果类型是结构或类,编译器给出的名称会略有不同。

然后链接器找不到正确的定义,因为它正在寻找一个不同的定义:bar.cpp 用前向声明定义了一个,但目前它在 main 中调用。 cpp 实际声明已放置,因此在符号表中给出了不同的函数名称。

关于c++ - 将结构向前声明为类时出现 Visual C++ 2015 链接器错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33483623/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com