вызывающий конструктор класса в деструкторе того же класса - PullRequest
1 голос
/ 05 мая 2010

Эксперты !! Я знаю, что этот вопрос - один из паршивых, но все же я осмелился открыть свой разум, надеясь, что научусь у всех.

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

Я не знаю, требуется ли это когда-либо в реальном программировании, я не могу вспомнить сценарии реального времени, когда нам действительно нужно вызывать функции / CTOR в нашем деструкторе. Обычно деструктор предназначен для очистки.

Если мое понимание верно, почему компилятор не жалуется? Это потому, что оно действительно по каким-то веским причинам? Если да, то что они?

Я пробовал использовать компилятор Sun Forte, g ++ и VC ++, и никто из них не жаловался на это. \

Редактировать: Я благодарю всех за их ответы, я думаю, что не совсем четко изложил свою точку зрения, я знал результат, он закончится рекурсивно, и программа может завершиться сбоем, но на самом деле вопрос о том, разрешает ли Деструктор создать объект.

<br>
using namespace std;
class test{
   public:
    test(){
       <code>cout<<"CTOR"<<endl;</code>
     }</p>

~test() {cout<<"DTOR"<<endl;
 test();
 }};

Ответы [ 5 ]

3 голосов
/ 05 мая 2010

Когда выполняется следующее

test();

вы создаете временный (новый) объект, который немедленно уничтожается, когда управление «проходит через точку с запятой», вызывается деструктор для этого временного объекта, который создает другой временный объект и т. Д. рекурсивные вызовы, которые приводят к переполнению стека и сбою вашей программы.

Запрещать деструктору создавать временные объекты было бы смешно - это сильно ограничивало бы вас в том, какой код вы могли бы исправить. Также это не имеет смысла - деструктор уничтожает текущий объект, и эти временные объекты совершенно не имеют отношения к , поэтому навязывать им такие ограничения бессмысленно.

1 голос
/ 05 мая 2010

Этот код, который дает тестовым экземплярам большой размер, фактически очень быстро вызывает переполнение стека из-за бесконечной рекурсии:

#include <iostream>
using namespace std;
class test{
   public:
    int a[10000];
    test(){
     }

~test() {
 test();
 }};

int main() {
    test t;
}

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

1 голос
/ 05 мая 2010

Инструменты статического анализа - это то, на что следует жаловаться.Для меня ваш случай не сильно отличается от следующего:

void foo();
void bar()
{
   foo();
}
void foo()
{
   bar();
}

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

РЕДАКТИРОВАТЬ: В вашем случае проблема гораздо проще.Это обычная бесконечная рекурсия, потому что идея вашего деструктора выглядит примерно так:

   ~test()
   {
      cout<<"DTOR"<<endl;
      test tmp();
      tmp.~test(); // infinite recursion.
   }
1 голос
/ 05 мая 2010

Насколько я понимаю, вы просто создаете новый объект test в деструкторе и оставляете его нетронутым.

0 голосов
/ 05 мая 2010

Я не вижу причин, почему это должно быть незаконно, но я признаю, что изо всех сил пытаюсь найти достойный пример того, почему я это сделаю. Чтобы это работало, вам нужно условно вызывать c'or, а не безоговорочно.

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