虚拟析构函数Arduino由于未定义引用操作员删除

时间:2019-04-17 22:17:40

标签: c++

当接口包含纯虚拟方法时,建议使用虚拟析构函数。例如,我有以下代码:


    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的析构函数中删除虚拟关键字时,它也会给我同样的错误消息。

1 个答案:

答案 0 :(得分:0)

很奇怪的是,析构函数的唯一存在会引入对全局operator delete的引用。但是,您似乎并不是第一个遇到此问题的人:Undefined reference to 'operator delete(void*)'。如此处的评论所指出的,C ++标准库位于avr-g++上的not really available上,这很可能也是您所使用的。

尽管如此,我相信我可以提供一些帮助。

  

当接口包含纯虚拟方法时,建议使用虚拟析构函数。

仅当您需要通过基本指针[expr.delete]/3 delete来使用对象时,才需要虚拟析构函数。将虚拟析构函数视为接口本身的一部分。如果接口声明了虚拟析构函数,则意味着“可以删除实现此接口的对象”。 delete操作成为界面的一部分。

如果您不需要将delete作为接口的一部分的功能(我认为实际上应该是默认值),则不需要虚拟析构函数。只需声明析构函数为非虚拟的并使其受到保护即可。因此,您可以从接口中删除操作delete,然后再决定是否可以将类型进一步删除,以进一步实现接口的具体实现……