Наследование от контейнера с невиртуальным деструктором

StackOverflow https://stackoverflow.com/questions/2148970

Вопрос

Я пытаюсь использовать прямые объявления и общие указатели, чтобы устранить некоторые зависимости include.Все работает хорошо, за исключением того, что я использовал xList typedefs для удобства чтения во многих местах (например: typedef QList<X> XList).

Обходной путь для проблемы с прямым объявлением typedef заключается в использовании наследования: class XList : public QList<X>{};.QList имеет невиртуальный деструктор.Учитывая тот факт, что собственный QStringList Qt наследует QList<QString> и я не распределяю XLISTS в куче, вы видите какие-либо проблемы с этим обходным путем?Должен ли я явно запретить выделение кучи для классов xList?

Это было полезно?

Решение

Давайте посмотрим, что произойдет, если мы определим XList вот так:

class XList : public QList<X> {};

Следующее будет работать так, как ожидалось:

  XList* x = new XList;
  delete x;

Однако следующее не будет:

  QList<X>* q = new XList;
  delete q;

QList<X>деструктор 's будет вызван, но не XList's, если таковые имеются.Это то, что виртуальный деструктор в базовом классе сделает для вас.

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

Убедитесь, что это предположение задокументировано, и сделайте XList's new operator private для предотвращения создания экземпляра кучи, как вы упомянули.

Безопасной альтернативой было бы создание QList<X> член вашего XList, то есть:предпочитаю инкапсуляцию наследованию.

Другие советы

QStringList не определяет свой собственный деструктор.В этом случае, даже если QList был использован полиморфно (см. Пример blue.tuxedo), проблемы нет, поскольку, хотя деструктор производного класса не будет вызван, он не определен.

В вашем случае, если вам требуется деструктор в вашем производном классе (XList), вы столкнетесь с проблемами.Ранее было обсуждение того, как обойти невозможность пересылать определения типов declare здесь:

Прямое объявление typedef в C ++

Если вы можете избежать написания производного класса, возможно, вам будет лучше в долгосрочной перспективе.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top