Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Исключение нужно бросить в конструкторе. Как поступаете в таких случаях? 
V
    Опции темы
 
Исключения, бросаемые в конструкторе, - что вы с ними делаете?
ничего не делаю: надо бросить - бросаю [ 24 ]  [48.98%]
стараюсь не бросать исключений в конструкторах, но иногда приходится [ 11 ]  [22.45%]
никогда не бросаю исключений в конструкторах [ 8 ]  [16.33%]
бросаю исключения только в конструкторах [ 1 ]  [2.04%]
не выбрасываю исключение, а делаю что-то другое (написать, что именно). [ 5 ]  [10.20%]
Всего проголосовавших: 49
В этом опросе возможен один вариант ответа
Гости не могут голосовать 
archimed7592
Дата 10.1.2008, 00:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(JackYF @  9.1.2008,  23:47 Найти цитируемый пост)
Ещё варианты? 

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

Код

void stupid_func()
{
   void *p1 = operator new(100);
   if (std::rand() % 2)
      throw 0;
   void *p2 = operator new(200);
   // ...
   operator delete(p1);
   operator delete(p2);
}

void smart_func()
{
   std::auto_ptr< T > p1(new T());
   if (std::rand() % 2)
      throw 0;
   std::auto_ptr< T > p2(new T());
   // ...
}

Отгадай к какой из двух ф-ции относится предложенный тобою конструктор smile.
Аналогично ф-циям работают и конструкторы. Если он завершится исключением, то деструктор вызван не будет, но, будут вызваны деструкторы уже сконструированных полей и деструкторы базовых классов.

Почитай что-нибудь на тему базовой/строгой гарантии бессбойности в случае исключения smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
JackYF
Дата 10.1.2008, 00:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(archimed7592 @  9.1.2008,  23:08 Найти цитируемый пост)
Отгадай к какой из двух ф-ции относится предложенный тобою конструктор

вообще говоря, ни к одной. Итак, мой пример:
Код

#include <iostream>

class A
{
 public:
    ~A()
    {
        std::cout << "I'm destructor of A\n";
    }
};


class B
{
 public:
    ~B()
    {
        std::cout << "I'm destructor of B\n";
    }
};

class S
{
 private:
     A* pa;
     B* pb;
 public:
    S()
    {
         pa = new A;
         throw 0;
         pb = new B;
    }
    ~S()
    {
        delete pa;
        delete pb;
    }
};

int main()
{
    try
    {
        S* ps = new S;
        delete ps;
    }
    catch(...)
    {}
}


Почему не отработал деструктор класса A?



--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 10.1.2008, 00:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(JackYF @  10.1.2008,  00:32 Найти цитируемый пост)
вообще говоря, ни к одной

Если дописать rand, то очень смахивает на первую ф-цию smile.


Цитата(JackYF @  10.1.2008,  00:32 Найти цитируемый пост)
Почему не отработал деструктор класса A?

А почему он должен отрабатывать? Деструктор вызывается для сконструированных объектов. Для недоконструированных деструктор не вызывается. Т.е. не то, что до delete pa не доходит - до самого деструктора не доходит.
А вот немного модифицированный пример что выведет? smile

Код

struct E
{
  E()
  { throw 0; }
};

struct S
{
  A a;
  E e;
  B b;
};

int main()
{
   try { S s; } catch(...) { ; }
}


Добавлено через 3 минуты и 21 секунду
Кстати, учитывая поздний час и теоритическую сонность собеседников ещё раз упомяну:
Цитата(archimed7592 @  10.1.2008,  00:08 Найти цитируемый пост)
Аналогично ф-циям работают и конструкторы. Если он завершится исключением, то деструктор вызван не будет, но, будут вызваны деструкторы уже сконструированных полей и деструкторы базовых классов.




--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
bsa
Дата 10.1.2008, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(JackYF @ 10.1.2008,  00:32)
Почему не отработал деструктор класса A?

ответ на этот вопрос ты и сам знаешь.
Вот archimed7592 предложил интересный вариант с использованием auto_ptr. В этом случае проблем быть уже не должно:
Код
class S
{
 private:
     A* pa;
     B* pb;
 public:
    S()
    {
         std::auto_ptr<A> apa(pa = new A);
         throw 0;
         std::auto_ptr<B> apb(pb = new B);
         apa.release();
         apb.release();
    }
    ~S()
    {
        delete pa;
        delete pb;
    }
};

PM   Вверх
Fazil6
Дата 10.1.2008, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата(JackYF @  9.1.2008,  23:32 Найти цитируемый пост)
Почему не отработал деструктор класса A?
 ну естественно к динамически создаваемым объектам это не относится. Юзаем shared_ptr и проблема решена

PM MAIL   Вверх
JackYF
Дата 10.1.2008, 01:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(bsa @  9.1.2008,  23:45 Найти цитируемый пост)
ответ на этот вопрос ты и сам знаешь.

Да, я задал его archimed7592у. Имелось в виду, что не всё так хорошо.

Отличия (семантико-логические) конструктора от любой другой обычной фукнции в том, что конструктор может работать с динамическими объектами напрямую, так как он "знает", что всегда есть (при наличии нормального программиста smile) деструктор, который корректно освободит память из-под динамических объектов.
Функция же должна надеяться только сама на себя - пары, которая вызовется к ней, нет, поэтому должна по возможности содержать объекты локальной области видимости, для которых в случае исключения вызовется деструктор. Только и всего.

Цитата(bsa @  9.1.2008,  23:45 Найти цитируемый пост)
В этом случае проблем быть уже не должно:

Да, неплохо. Хотя присутствует небольшой оверхед - в дополнении к вызовам двум операторов new и двум присваиваниям, мы имеем вызов двух конструкторов, двух деструкторов, двух функций. Впрочем, это должны быть мелочи...

Пошёл-ка я и вправду спать...


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 10.1.2008, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(JackYF @  10.1.2008,  01:06 Найти цитируемый пост)
Отличия (семантико-логические) конструктора от любой другой обычной фукнции в том, что конструктор может работать с динамическими объектами напрямую, так как он "знает", что всегда есть (при наличии нормального программиста smile) деструктор, который корректно освободит память из-под динамических объектов.

Выкинь эти стереотипы из головы smile. Конструктор - точно такая же ф-ции и к нему предъявляются точно такие же требования безопасности относительно исключений.

Цитата(JackYF @  10.1.2008,  01:06 Найти цитируемый пост)
Функция же должна надеяться только сама на себя - пары, которая вызовется к ней, нет, поэтому должна по возможности содержать объекты локальной области видимости, для которых в случае исключения вызовется деструктор.

Конструктор, пока он не завершится тоже должен надеятся только на себя.

И вообще - всё что ты описал относится к объектам, а не к конструкторам. А пока конструктор не завершился объекта никакого нет.

Цитата(JackYF @  10.1.2008,  01:06 Найти цитируемый пост)
Хотя присутствует небольшой оверхед

Оверхэда нет smile.


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
Earnest
Дата 10.1.2008, 08:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Ребята, ну вы и зацепились...
Очевидно, что исключения сами по себе не панацея. И в любой другой функции (не только в конструкторе), если несколько раз выделять память и присваивать ее встроенным указателям, возникновение исключения где-нибудь посредине приведет к утечкам - если не принимать специальных мер. И не только памяти - любой ресурс - открытие файла, создание каких-нибудь объектов ядра и прочаяя. Добавим сюда идиому "Выделение ресурса есть инициализация" и все сразу щастливы. Оверхеды, конечно, есть (у "умных" указателей по сравнения с "глупыми" и прочих оберток), но при нормальном кодировании почти всегда мизерны - скажем, в случае с auto_ptr в релиз-версии будет просто присваивание (а не вызов конструктора) ну и т.д. 
archimed7592 молодец, для 2 часов ночи складно излагаешь smile  


--------------------
...
PM   Вверх
Lazin
Дата 10.1.2008, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Очевидно, что если в ручную управлять памятью, код будет совсем немного, но быстрей, но это не стоит безопасности по отношению к исключениям, и прочих радостей ручного управления памятью.
PM MAIL Skype GTalk   Вверх
JackYF
Дата 10.1.2008, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Спасибо всем за за объяснения, вопрос закрыт.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
Earnest
Дата 10.1.2008, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(Lazin @  10.1.2008,  10:09 Найти цитируемый пост)
Очевидно, что если в ручную управлять памятью, код будет совсем немного

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


--------------------
...
PM   Вверх
Lazin
Дата 10.1.2008, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Earnest, я имею ввиду скорость выполнения кода, так как обычно, оправдание не использования auto_ptr, shared_ptr и т.п. является как-раз якобы имеющее место падение производительности. Лично я стараюсь как можно реже использовать "голые" указатели, и чаще "умные", чего и всем желаю))
PM MAIL Skype GTalk   Вверх
UnrealMan
Дата 10.1.2008, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(Earnest @  9.1.2008,  20:24 Найти цитируемый пост)
Строго говоря, что в конструкторе исключения бросать, что в других функция - лишь бы не в деструкторе.

А я и в деструкторе не стесняюсь бросать smile

PM MAIL   Вверх
archimed7592
Дата 10.1.2008, 20:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(UnrealMan @  10.1.2008,  20:12 Найти цитируемый пост)
А я и в деструкторе не стесняюсь бросать smile

А что дальше? Abnormal termination? Или всё же "корректная" работа? smile


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
UnrealMan
Дата 10.1.2008, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



А дальше ловим его в том же деструкторе и обрабатываем функтором-обработчиком (при этом деструктор не знает, как именно должна происходить обработка исключения).

Это сообщение отредактировал(а) UnrealMan - 10.1.2008, 20:19
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0650 ]   [ Использовано запросов: 24 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.