You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS2017下为未导出C++接口添加虚析构函数触发LNK2019错误的原因是什么

问题根本原因解析

1. 纯虚析构函数的特殊语法要求

C++标准对纯虚析构函数有特殊规定:哪怕析构函数被声明为纯虚(=0),也必须提供对应的实现。
这和普通纯虚函数完全不同:普通纯虚函数(比如你代码里的foo()、bar())不需要基类实现,多态调用时会直接跳转至派生类的覆盖实现,链接阶段不会要求基类提供对应函数的符号。但析构函数的调用逻辑是编译器强制的:派生类对象析构时,执行完派生类自身的析构逻辑后,一定会自动调用基类的析构函数,无论基类析构是不是纯虚的。你的报错信息里也明确提到,派生类B的析构函数引用了IX的析构函数,就是这个强制调用导致的。

2. 未导出DLL类的符号可见性规则

你最开始没有显式声明IX的析构函数时,编译器会自动生成默认的内联公有析构函数,内联函数的实现会在调用点直接展开,不需要依赖DLL导出的符号,因此不会触发链接错误。
当你显式声明了virtual ~IX() = 0之后,这个析构函数不再是编译器隐式生成的内联实现:

  • 如果你没有额外提供IX析构的实现,链接阶段必然找不到符号
  • 哪怕你在DLL内部提供了IX析构的实现,由于整个IX类没有做导出处理,这个实现的符号也只对DLL内部可见,外部调用的模块(你的test_project)无法访问到该符号,依然会报链接错误。
常见解决方案说明

你提到的两种方案刚好对应上面的两个问题根源:

  • 导出IX接口:DLL会把~IX()的实现符号导出,外部模块链接时可以找到该符号完成重定位
  • 给析构函数添加=default实现:相当于要求编译器生成内联的默认析构实现,调用时直接在调用点展开,不需要依赖DLL的导出符号,无需导出类也能正常编译链接。

内容的提问来源于stack exchange,提问作者TonySalimi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 04:30:05