当接口包含纯虚拟方法时,建议使用虚拟析构函数。例如,我有以下代码:
template class A { protected: char buffer[Size]; public: virtual void method() = 0; A() = default; virtual ~A() = default; }; template class B : public A { public: void method() override; B() = default ~B() = default; }; int main() { B b; b.method(); }
但是当我尝试使用g ++为Arduino Due进行编译时,出现以下错误:
main.cpp:(.text._ZN4r2d29robot_arm22uarm_gcode_generator_cILj100EED0Ev[_ZN4r2d29robot_arm22uarm_gcode_generator_cILj100EED5Ev]+0x6): undefined reference to `operator delete(void*, unsigned int)'
但是,当我从A完全删除析构函数时,它删除了错误,但是这是否会导致Undifed行为?另外,当我只是从A的析构函数中删除虚拟关键字时,它也会给我同样的错误消息。
答案 0 :(得分:0)
很奇怪的是,析构函数的唯一存在会引入对全局operator delete
的引用。但是,您似乎并不是第一个遇到此问题的人:Undefined reference to 'operator delete(void*)'。如此处的评论所指出的,C ++标准库位于avr-g++
上的not really available上,这很可能也是您所使用的。
尽管如此,我相信我可以提供一些帮助。
当接口包含纯虚拟方法时,建议使用虚拟析构函数。
仅当您需要通过基本指针[expr.delete]/3 delete
来使用对象时,才需要虚拟析构函数。将虚拟析构函数视为接口本身的一部分。如果接口声明了虚拟析构函数,则意味着“可以删除实现此接口的对象”。 delete
操作成为界面的一部分。
如果您不需要将delete
作为接口的一部分的功能(我认为实际上应该是默认值),则不需要虚拟析构函数。只需声明析构函数为非虚拟的并使其受到保护即可。因此,您可以从接口中删除操作delete
,然后再决定是否可以将类型进一步删除,以进一步实现接口的具体实现……