Подтвердить что ты не робот

Компиляция С++ без оператора delete

Я пишу программу на С++ для встроенного устройства, и я хочу скомпилировать ее без libstdС++, исключений и динамического выделения памяти.

Пример программы:

#include <stdio.h>

class A
{
public:
    virtual ~A() {}
    virtual void Foo() = 0;
};

class B : public A
{
public:
    virtual ~B() {}
    virtual void Foo() override{}
};

int main()
{
    B b;
    return 0;
}

Сразу же я столкнулся со следующими ошибками.

$gcc src.cpp -static -fno-rtti -fno-exceptions -std = С++ 11

/tmp/ccd0Wydq.o: В функции A::~A()': src.cpp:(.text._ZN1AD2Ev[_ZN1AD5Ev]+0x29): undefined reference to оператор delete (void *) '/tmp/ccd0Wydq.o: В функции A::~A()': src.cpp:(.text._ZN1AD0Ev[_ZN1AD5Ev]+0x20): undefined reference to оператор delete (void *)'/tmp/ccd0Wydq.o: В функции B::~B()': src.cpp:(.text._ZN1BD2Ev[_ZN1BD5Ev]+0x35): undefined reference to operator delete (void *) '/tmp/ccd0Wydq.o: В функции B::~B()': src.cpp:(.text._ZN1BD0Ev[_ZN1BD5Ev]+0x20): undefined reference to оператор delete (void *)' /tmp/ccd 0Wydq.o:(.rodata._ZTV1A[_ZTV1A]+0x20): undefined ссылка на `__cxa_pure_virtual 'collect2: ошибка: ld возвращен 1 статус выхода Makefile: 2: рецепт для цели "все" не выполнен: *** [все] Ошибка 1

Я понимаю, зачем нужен __cxa_pure_virtual, но не мог для меня жизнь понять, зачем мне нужна реализация delete.

Я выполняю операции new или delete в коде, зачем это нужно?

При реализации обеих функций для удовлетворения требований к компоновщикам кажется, что они не называются (как и ожидалось).

Есть ли способ избежать реализации этих функций?

4b9b3361

Ответ 1

Когда виртуальный деструктор вызывается с помощью выражения delete, вызываемый operator delete определяется из области самого производного класса. Например,

#include <iostream>

class Base {
public:
    virtual ~Base() {}
};

void destroy_base(Base* b) { delete b; }

class Derived : public Base {
public:
    static void operator delete(void* ptr) {
        std::cout << "Derived::operator delete\n";
        ::operator delete(ptr);
    }
};

int main() {
    destroy_base( new Derived );
}

выводит "Derived::operator delete", хотя функция destroy_base не знает класс Derived.

g++ реализует это, помещая две версии деструктора в каждый класс vtable: тот, который просто разрушает члены и базы, и тот, который делает все это, а затем вызывает соответствующий operator delete. Здесь появляются ваши символы undefined.

Если вы никогда не используете выражение delete, просто опустите функцию ::operator delete, и вы должны быть в порядке.