LINUX.ORG.RU

История изменений

Исправление vtVitus, (текущая версия) :

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

Чтоб можно было доделать то, что было не доделано в деструкторе. Повторный вызов delete не будет вызывать деструктор (базовый вызовет!!!) в котором произошло исключение, но и память не удалит. Пример

user@xxx:/tmp$ cat ex2.cc
#include <exception>
#include <iostream>

class Base {
        public:
        virtual ~Base() {
                std::cout << "Base" << std::endl;
        }

};

void somecall(int i) {
        if (i == 0) throw i;
}

class Test : public Base {
        int i;
public:
        Test(int _i):i(_i){}

        virtual ~Test()
        {
                std::cout << "Test" << std::endl;
                somecall(i);
                close();
        }

        void set(int _i) {
                i = _i;
        }
        void close() {
                std::cout << "close " << i << std::endl;
        }
};

void g()
{
        Test * d1 = new Test(0);
        try {
                delete d1;
        }  catch(int i) {
                std::cout << "exception " << i << std::endl;
                d1->close();
                try {
                        delete d1;
                } catch(int i) {
                        std::cout << "no exception " << i << std::endl;
                }
        }
}

int main()
{
  g();
}
user@xxx:/tmp$ g++ ex2.cc
user@xxx:/tmp$ ./a.out
Test
Base
exception 0
close 0
Base

Исходная версия vtVitus, :

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

Чтоб можно было доделать то, что было не доделано в деструкторе. Повторный вызов delete не будет вызывать деструктор (базовый вызовет!!!), но удалит память ( во всяком случае в g++) Пример

user@xxx:/tmp$ cat ex2.cc
#include <exception>
#include <iostream>

class Base {
        public:
        virtual ~Base() {
                std::cout << "Base" << std::endl;
        }

};

void somecall(int i) {
        if (i == 0) throw i;
}

class Test : public Base {
        int i;
public:
        Test(int _i):i(_i){}

        virtual ~Test()
        {
                std::cout << "Test" << std::endl;
                somecall(i);
                close();
        }

        void set(int _i) {
                i = _i;
        }
        void close() {
                std::cout << "close " << i << std::endl;
        }
};

void g()
{
        Test * d1 = new Test(0);
        try {
                delete d1;
        }  catch(int i) {
                std::cout << "exception " << i << std::endl;
                d1->close();
                try {
                        delete d1;
                } catch(int i) {
                        std::cout << "no exception " << i << std::endl;
                }
        }
}

int main()
{
  g();
}
user@xxx:/tmp$ g++ ex2.cc
user@xxx:/tmp$ ./a.out
Test
Base
exception 0
close 0
Base