【发布时间】:2011-04-03 09:53:36
【问题描述】:
考虑以下几点:
在X.h:
class X
{
X();
virtual ~X();
};
X.cpp:
#include "X.h"
X::X()
{}
尝试构建它(我正在使用 .dll 目标来避免丢失的 main 错误,并且我正在使用 Visual Studio 2010):
错误 1 错误 LNK2001: 无法解析的外部符号“private: virtual __thiscall X::~X(void)” (??1X@@EAE@XZ)
不过,小的修改会导致构建成功:
X.h:
class X
{
inline X(); // Now inlined, and everything builds
virtual ~X();
};
或
X.h:
class X
{
X();
~X(); // No longer virtual, and everything builds
};
当 .dtor 是虚拟的或 .ctor 未内联时,是什么导致链接器中未解析的外部?
编辑:
或者,也许更有趣的是,如果我将析构函数设为非虚拟,或者如果我内联构造函数,为什么我不得到一个未解析的外部?
【问题讨论】:
-
我确定我理解问题/变体,但底线是:如果要调用它,它需要一个定义。在您的第一个变体中,您从未定义析构函数,这正是错误所说的。我看不到变体是如何构建的,因为我仍然看不到构造函数或析构函数的定义。
-
但他们确实如此。因此我的困惑。这是一个非常简单的代码示例,我的同事都没有对此行为给出明确的答案。最好的猜测是某些东西是未定义的,我们最终会进入特定于供应商的领域,但我很好奇究竟是什么未定义会触发不同的行为。
-
除非您向我们展示您正在构建的所有内容,否则无法告诉我们!
-
@Martin York:这就是我正在构建的一切!字面上地!好的,我可能在其中一个文件前省略了回车,但说真的,这就是项目中的所有内容。您可以在 20 秒内将其复制到您自己的暂存库中。就是这么简单。
-
在第一个中它需要析构函数的地址来构建虚拟表。在第二个中:由于从未实际构建构造函数,因此它永远不需要构建虚拟表,因此不需要析构函数的地址。在第三个中,我们在构建构造函数时不需要析构函数的地址(因为它不再在虚拟表中);。
标签: c++ destructor unresolved-external virtual-functions