Почему виртуальный деструктор требует удаления оператора? - PullRequest
2 голосов
/ 08 июля 2019

Рассмотрим следующий код:

class Base {
public:
#ifdef __VIRTUAL__
   virtual ~Base() {}
#else
   ~Base() {}
#endif
};

class Derived : public Base {
public:
    ~Derived() {}
private:
    static void operator delete(void*) = delete;
};

int main() {
    Derived d;
}

Он будет успешно скомпилирован с cmd

g++ -std=c++11 main.cpp

, но не с cmd

g++ -std=c++11 -D__VIRTUAL__ main.cpp

Выходные данные показываютoperator delete требуется

main.cpp: In destructor ‘virtual Derived::~Derived()’:
main.cpp:12:17: error: use of deleted function ‘static void Derived::operator delete(void*)’
     ~Derived() {}
                 ^
main.cpp:14:17: error: declared here
     static void operator delete(void*) = delete;
                 ^
main.cpp: In destructor ‘virtual Derived::~Derived()’:
main.cpp:12:17: error: use of deleted function ‘static void Derived::operator delete(void*)’
     ~Derived() {}
                 ^
main.cpp:14:17: error: declared here
     static void operator delete(void*) = delete;
                 ^

Это означает, что если я использую функцию виртуального деструктора, я не могу удалить operator delete.

Почему это произошло, почему виртуальному деструктору необходим глобальный operator delete, даже если он создан в стеке.

1 Ответ

1 голос
/ 08 июля 2019

Функция operator delete вызывается только при удалении объекта с динамическим сроком хранения.Он не вызывается вашей программой.

Однако стандарт требует, чтобы эта функция была доступна, если существует виртуальный деструктор, даже если объект никогда не используется динамически.

В C ++17 стандарт это [class.dtor] / 13:

В точке определения виртуального деструктора (включая неявное определение) функция освобождения не-массива определяется так, как если бывыражение delete this появляется в не виртуальном деструкторе класса деструктора.Если поиск не удался или если у функции освобождения есть удаленное определение, программа некорректна.[Примечание: Это гарантирует, что функция освобождения, соответствующая динамическому типу объекта, доступна для delete-expression .—Конец примечания]

Почему стандарт требует этого?Я понятия не имею, но вам нужно будет найти какой-то другой подход для решения вашей проблемы.Может быть, этот поток будет полезен: Любой способ предотвратить динамическое выделение класса?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...