Мне дали стороннюю библиотеку с ее заголовком для использования. Теперь в этой библиотеке есть класс «Base». Проблема этого класса в том, что у него нет виртуального деструктора. Теперь, когда у меня нет стороннего кода, я не могу вносить изменения там.
Мне сказали написать несколько производных классов с этим и убедиться, что объект очищается правильно, когда объекты удаляются. Как мы можем достичь этого?
Спасибо за ответ, похоже, у меня есть только 2 варианта.
1) положить виртуальный деструктор в производный класс
2) использовать композицию.
Я планирую использовать подход № 1. Я планирую иметь класс, производный от оболочки, с виртуальным деструктором. А затем используйте этот производный класс-оболочку для дальнейшей деривации. Ниже приведен код.
//++ THIRD PARTY HEADER
class base
{
public:
~base(){ }
};
//-- THIRD PARTY HEADER//++ MY CODE
// wrapper polymorphic base.
class polymorphic_base
{
public:
virtual ~polymorphic_base() { }
};
class derived1 : polymorphic_base
{
/// derived 1
};
class derived2 : polymorphic_base
{
/// derived 2
}void foo(polymorphic_base *pb)
{
// use pb
// use pb
delete pb;
}//-- MY CODE
Пожалуйста, дайте мне знать, если этот подход будет хорошо?
Если деструктор производного класса public
и не виртуальный, то это означает, что разработчик третьей стороны не хочет, чтобы их класс использовался для полиморфного наследования.
Если в вашем плане реализации есть сценарий удаления объекта производного класса, на который указывает указатель базового класса, тогда базовый класс не имеет virtual
деструктор приведет к неопределенному поведению.
Если в вашем плане реализации нет вышеупомянутого сценария, вы все равно можете получить класс без каких-либо проблем.
В первом случае, поскольку у вас нет кода для этого базового класса, вы не сможете преодолеть этот разгром. Лучшее, что вы можете сделать, это рассмотреть has-a
отношения, а не is-a
отношения и попытаться заставить его работать на вас.
С Base
деструктор не виртуальный, если вам нужно поддерживать delete
из Base*
тогда тебе просто не повезло.
В противном случае, чтобы
«Убедитесь, что объект очищается правильно, когда объекты удаляются»
просто добавьте виртуальный деструктор в ваш производный класс Derived
,
Но вы уверены, что требование действительно, буквально, «когда объекты удаляются»? Потому что гораздо лучший путь вперед будет запретить динамическое распределение. Что вы можете сделать в коде, сделав практически непригодным то, что new
-выражение потребностей, таких как функция выделения (например, ограничить ее доступность), и которую вы можете сделать еще проще, просто указав в документации, что динамическое распределение не поддерживается.
Могли бы быть даже лучшие решения, если бы вы могли уточнить, какова цель получения классов из Base
, Может быть, вам не нужен вывод классов. Может быть, вы можете обойтись с Base
член, скажем.