std :: unique_ptr базового класса, содержащего ссылку на производный класс, не показывает предупреждение в компиляторе gcc, в то время как голый указатель показывает это. Зачем? - программирование
Подтвердить что ты не робот

std :: unique_ptr базового класса, содержащего ссылку на производный класс, не показывает предупреждение в компиляторе gcc, в то время как голый указатель показывает это. Зачем?

У меня есть иерархия базового класса и производного класса. Базовый класс имеет одну виртуальную функцию, которая переопределяется производным классом.

class Base
{  
public:  
    ~Base();    
    virtual void other_functionality() = 0;  
};

class Derived : public Base
{  
public:  
    ~Derived ();    
    void other_functionality() {//some code};  
};

Теперь, если я делаю так:

int main()
{
Base * P = new Derived ();
delete p;
return 0;
}

Это дает ошибку:
удаление объекта типа полиморфного класса, который имеет не виртуальный деструктор.

Но с unique_ptr это проходит без предупреждения.

int main()
{
 std::unique_ptr<Base> p;
 p.reset(new Derived ());

return 0;
}

Я знаю, использую ли я виртуальный деструктор. Предупреждение с голым указателем будет решено. Но остается вопрос - почему отсутствие виртуального деструктора показывает проблему с голым указателем, а не с unique_ptr.

4b9b3361

Ответ 1

Ну, во-первых, удаление производного объекта через базовый указатель, когда базовый класс не имеет виртуального деструктора, является неопределенным поведением. Компиляторы не обязаны диагностировать неопределенное поведение…

При этом причина, по которой это предупреждение не появляется при использовании std::unique_ptr, наиболее вероятна из-за того, что GCC не сообщает о предупреждениях, которые появляются в системных заголовках.

Ответ 2

Я не могу найти ссылку, но я видел обсуждение этого онлайн, в базе данных ошибок GCC.

Предупреждение выдается на фактическое выражение delete. В случае unique_ptr delete вызывается внутри системного заголовочного файла.

Согласно обсуждению в этом отчете об ошибках, реализация системных библиотек C++ требует всевозможных компромиссов, которые приводят к различным предупреждениям. Поэтому предупреждения ограничены внутри системных заголовков. Вот почему вы не увидите предупреждение, которое ожидаете.

Обновление: и вот оно, прямо изо рта лошади:

https://gcc.gnu.org/onlinedocs/cpp/System-Headers.html

Заголовочные файлы, объявляющие интерфейсы к операционной системе и библиотекам времени выполнения, часто не могут быть записаны в строго соответствующем C. Следовательно, GCC придает коду, найденному в системных заголовках, специальную обработку. Все предупреждения, кроме предупреждений, генерируемых #warning (см. Диагностика), подавляются, пока GCC обрабатывает системный заголовок.

Ответ 3

Я очень рад сообщить всем, что недавно полностью вылечился от моего HSV 1 & 2. Я использовал масло орегано, кокосовое масло, ацикловир, валацикловир, фамцикловир и некоторые другие продукты, и это действительно помогло во время моих вспышек, но я полностью вылечился от моего ВПГ с помощью сильного и активного растительного лекарственного средства, заказанного у сильного травника, и он полностью боролся вирус из моей нервной системы, и я получил отрицательный результат после 12 дней использования фитотерапии. Я здесь для того, чтобы вы знали, что вирус герпеса, ВИЧ и других заболеваний полностью излечим, и я избавился от них с помощью травяной медицины доктора Косу. Он также вылечил моего двоюродного брата ВИЧ 2 года назад. Он также заклинатель заклинаний. Он использовал заклинание, чтобы восстановить разрушенные браки, заклинание удачи, чтобы превзойти и преуспеть в жизни, а также сдать экзамены и преуспеть в бизнесе. Свяжитесь с ним по электронной почте: [email protected] Позвоните/напишите ему на WhatsApp +2349026804066.