Метод Free нужен публичный, он делает некоторые вещи (по освобождению ресурсов) общие для всех унаследованных классов, и плюс каждый класс должен не забыть реализовать метод освобождения специфических для него ресурсов FreeResource. Но понятно что в деструкторе будет вызываться чисто виртуально абстрактный метод базового класса (FreeResource() = 0). Как быть?
S>Метод Free нужен публичный, он делает некоторые вещи (по освобождению ресурсов) общие для всех унаследованных классов, и плюс каждый класс должен не забыть реализовать метод освобождения специфических для него ресурсов FreeResource. Но понятно что в деструкторе будет вызываться чисто виртуально абстрактный метод базового класса (FreeResource() = 0). Как быть?
Это неправильный дизайн. Сделайте, чтобы освобождение ресурсов выполнялось только при уничтожении объекта, в (виртуальном) деструкторе. Вместо вызова функции Free устройте, чтобы в этом месте объект уничтожился, например, введением дополнительного scope.
Re: Вызов вирт. метода из родительского деструктора
Здравствуйте, sanx, Вы писали:
S>Метод Free нужен публичный, он делает некоторые вещи (по освобождению ресурсов) общие для всех унаследованных классов, и плюс каждый класс должен не забыть реализовать метод освобождения специфических для него ресурсов FreeResource. Но понятно что в деструкторе будет вызываться чисто виртуально абстрактный метод базового класса (FreeResource() = 0). Как быть?
Почему бы не объявить виртуальный деструктор?
class BaseClass
{
public:
virtual ~BaseClass() { /* что то общее для всех */; }
};
Здравствуйте, sanx, Вы писали:
S>Как я понимаю такое невозможно (вот здесь читал http://easy-coding.blogspot.com/2009/09/blog-post.html). Но вот у меня такая задача:
S>class BaseClass S>{ S>public: S> ~BaseClass() { Free(); } S> void Free() { ЧТО-ТО_ОБЩЕЕ_ДЛЯ_ВСЕХ; FreeResource(); } S>protected: S> virtual void FreeResource() = 0; S>};
S>Метод Free нужен публичный, он делает некоторые вещи (по освобождению ресурсов) общие для всех унаследованных классов, и плюс каждый класс должен не забыть реализовать метод освобождения специфических для него ресурсов FreeResource. Но понятно что в деструкторе будет вызываться чисто виртуально абстрактный метод базового класса (FreeResource() = 0). Как быть?
то, что вы хотите сделать, уже придумано, и даже в лучшем чем вы задумали виде.
называется виртуальныц деструктор, почитайте внимательно про него
Re: Вызов вирт. метода из родительского деструктора
Это не будет работать. FreeResource вызывается в деструкторе базового класса, в это время наследник уже уничтожен, следовательно получим вызов чисто виртуального метода, что есть неизбежное падение программы. Во-вторых у тебя FreeResource у наследника в protected, так что надо либо friend использовать, либо переносить в public. А лучше вообще так не делать. Я тут уже как-то давно писал, что CRTP противопоказано для конструкторов и деструкторов.
Re[3]: Вызов вирт. метода из родительского деструктора
W>Это не будет работать. FreeResource вызывается в деструкторе базового класса, в это время наследник уже уничтожен, следовательно получим вызов чисто виртуального метода, что есть неизбежное падение программы. Во-вторых у тебя FreeResource у наследника в protected, так что надо либо friend использовать, либо переносить в public. А лучше вообще так не делать. Я тут уже как-то давно писал, что CRTP противопоказано для конструкторов и деструкторов.
Да, стормозил.
А какое решение здесь можно предложить?
Когда он умрет, его мозг заспиртуют в стакане
Re[4]: Вызов вирт. метода из родительского деструктора
Еще можно как-то попробовать закрытый деструктор + псевдодеструктор, правда, это не будет работать в том случае, если мы хотим размещать экземпляры класса не в куче, а на стеке. Но мне как-то не догнать почему виртуальный деструктор не годится для ваших целей. Приведи, плиз, минимальный пример использования класса.
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[5]: Вызов вирт. метода из родительского деструктора
_>Виртуальный деструктор в действии
_>Еще можно как-то попробовать закрытый деструктор + псевдодеструктор, правда, это не будет работать в том случае, если мы хотим размещать экземпляры класса не в куче, а на стеке. Но мне как-то не догнать почему виртуальный деструктор не годится для ваших целей. Приведи, плиз, минимальный пример использования класса.
Я не топикстартер, но виртуальный деструктор ничего не дает, так как автор хочет вызывать из базового класса виртуальную функцию FreeResource, а в деструкторе, как известно, виртуальные функции не работают.
Я сначала этого не понял, но тут глобальная проблема заключается в том, что мы хотим в деструкторе базового класса выполнить некое действие, связанное с производным классом, но на момент вызова деструктора базового объекта дочерний объект уже фактически уничтожен и находится в неопределенном состоянии.
Я пока что-то вообще не вижу никакого (во всяком случае, автоматического и приличного) решения этой проблемы в C++. Разве что, как сказали, менять архитектуру.
Когда он умрет, его мозг заспиртуют в стакане
Re: Вызов вирт. метода из родительского деструктора
Здравствуйте, sanx, Вы писали:
S>Как я понимаю такое невозможно (вот здесь читал http://easy-coding.blogspot.com/2009/09/blog-post.html). Но вот у меня такая задача:
S>class BaseClass S>{ S>public: S> ~BaseClass() { Free(); } S> void Free() { ЧТО-ТО_ОБЩЕЕ_ДЛЯ_ВСЕХ; FreeResource(); } S>protected: S> virtual void FreeResource() = 0; S>};
S>Метод Free нужен публичный, он делает некоторые вещи (по освобождению ресурсов) общие для всех унаследованных классов, и плюс каждый класс должен не забыть реализовать метод освобождения специфических для него ресурсов FreeResource. Но понятно что в деструкторе будет вызываться чисто виртуально абстрактный метод базового класса (FreeResource() = 0). Как быть?
Здравствуйте, Kerbadun, Вы писали:
K>Я не топикстартер, но виртуальный деструктор ничего не дает, так как автор хочет вызывать из базового класса виртуальную функцию FreeResource, а в деструкторе, как известно, виртуальные функции не работают.
Вот и не понятно: что значит из базового класса? Если из деструктора базового класса — то это ИМХО не имеет смысла, т.к. к моменту вызова деструктора базового класса производный класс уже уничтожен (если конечно не рассматривать экзотический случай явного вызова деструктора). Если при уничтожении объекта, с которым мы работаем через указатель на экземпляр базового класса — то это и есть область применения виртуального деструктора.
K>Я сначала этого не понял, но тут глобальная проблема заключается в том, что мы хотим в деструкторе базового класса выполнить некое действие, связанное с производным классом, но на момент вызова деструктора базового объекта дочерний объект уже фактически уничтожен и находится в неопределенном состоянии.
Ну, об этом можно было и не напоминать
K>Я пока что-то вообще не вижу никакого (во всяком случае, автоматического и приличного) решения этой проблемы в C++. Разве что, как сказали, менять архитектуру.
Псевдодеструктор, вызывающий виртуальную функцию, а затем — настоящий деструктор. Но назвать это решение приличным как-то не поворачивается язык. Что-то типа того, что описывается чуть ниже
. Конечно, придется закрыть деструктор, иначе никто не помешает клиенту вызывать delete вместо нашего псевдодеструктора; объекты при этом нельзя будет размещать на стеке. Правда, ничто не в силах запретить клиенту создать производный класс с открытым деструктором, что разнесет нашу башню из моржовой кости на куски. Ну это так, мысли вслух, в порядке легкого бреда
Люди! Люди, смотрите, я сошел с ума! Люди! Возлюбите друг друга! (вы чувствуете, какой бред?)
Re[7]: Вызов вирт. метода из родительского деструктора
Здравствуйте, Kerbadun, Вы писали:
K>Я пока что-то вообще не вижу никакого (во всяком случае, автоматического и приличного) решения этой проблемы в C++. Разве что, как сказали, менять архитектуру.