编译器是否确实会实施纯虚拟驱动器的实现
Does compiler really enforce implementation of pure virtual destructor?
要验证语句" compiler&链接器强制执行纯虚拟破坏者的功能主体。P> 编译而没有任何错误。那么,为什么在这种情况下,编译器没有选择执行功能主体的存在?class Base
{
public:
virtual ~Base()=0; // Pure virtual destructor
};
class Derived : public Base
{
public:
~Derived()
{
std::cout << "~Derived() is executed";
}
};
int main()
{
//Derived d; <<<
return 0;
}
,因为编译器(实际上是整个翻译过程)没有如果执行ODR 1 违反。根据[basic.def.odr/4]的C 标准:
每个程序应完全包含每个非内线的一个定义 该程序中使用ODR的功能或变量;没有诊断 必需的。该定义可以在程序中明确显示,它可以 可以在标准或用户定义的库中找到(当 适当)是隐式定义的(请参阅[class.ctor],[class.dtor] 和[class.copy])。每个内联函数应在每个中定义 使用ODR的翻译单元。
编译器完美地在其范围内确定您的程序实际上并未使用 2 Derived
的破坏者(因此是Base
的破坏者),并且只是不用打扰您。<<<<<<<<<<<<<<<<<<<<<</p>
2 "使用"某物意味着什么?
编译器是否真的强制执行纯虚拟破坏者的实现?
没有编译器没有这样做。
编译器将编译单元编译到对象文件,这就是为什么它
编译没有任何错误。
我认为几乎每个编译器都会在没有任何错误的情况下进行编译。但是链接者会抱怨。编译器仅将代码添加到对象文件中,以及由链接器限制的内外引用(用于静态链接)。
当然,如果您再次发表评论Derived d;
,该程序将不会链接,请参见在线演示。
更新
您在问题中显示的只是一个单个汇编单元,如果您将其链接为程序,则链接器可能会删除未使用的代码。Storryteller的答案对此说了很多。
如果您在MAIN中注释Derived
使用情况,并将Base
类的定义复制到另一个编译单元中并在此处添加destructor实现,您会发现两者都将链接在一起,并且结果程序将运行,而无需任何错误。编译器本身不在乎您是否包括标题的定义。我不建议这样做是为了生产性编程,而是要理解为什么编译器传统上不关心定义的完整性。大多数现实世界的汇编单元通常不完整。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 编译器是否确实会实施纯虚拟驱动器的实现