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

Поиск:

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


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


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

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



Собственно, сабж. По текущей архитектуре кода исключение должно броситься в конструкторе объекта, если инициализация прошла неуспешно. Код ошибки вернуть не могу - конструктор всё-таки smile.

А что вы делаете в таких случаях?


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


stravaganza
**


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

Репутация: 5
Всего: 39



JackYF, замечательный опрос!

Я ответил, что стараюсь не бросать исключений в конструкторах, но иногда приходится. А вообще, думаю, что у меня на этот счёт пробел в теоретических познаниях : ума не приложу, что ж ещё делать, если конструктору скормили, скажем, недопустимое значение аргумента. Хуже того, это какой-нить десятый сверху базовый конструктор, который вызывается по ":" из конструктора наследуемого класса... Интересно, какие будут идеи по поводу последнего варианта ответа.

Это сообщение отредактировал(а) marcusmae - 9.1.2008, 19:37


--------------------
ἀπὸ μηχανῆς θεός
PM MAIL ICQ GTalk   Вверх
archimed7592
Дата 9.1.2008, 19:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


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

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



Ответил 1-й вариант(надо бросить - бросаю), но есть у меня маленькое уточнение 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   Вверх
nickless
Дата 9.1.2008, 19:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



ИМХО если пользуешься исключениями, так пользуйся, а как раз в конструкторе удобно, не надо ничего изобретать.


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Earnest
Дата 9.1.2008, 20:24 (ссылка) |   (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Я выбрала первый вариант... Строго говоря, что в конструкторе исключения бросать, что в других функция - лишь бы не в деструкторе.
Однако на практике я делаю все же немного по-другому, особенно если речь идет о глобально используемых классах-объектах. Такой конструктор (который может привести к исключению) я делаю приватным и заворачиваю в фабричную функцию (обычно статик этого же класса). И она возвращает уже указатель или 0, обрабатывая исключения или просто проверяя условия внутри себя. 
Решение зависит от контекста - ведь исключения исключениям рознь. Неправильный параметр - если только его не пользователь ввел (или он откуда-то извне появился) - это должно быть выковырено на этапе отладки - здесь лучше исключения и\или ASSERT's.
А вот несуществующий файл или отсутствие ресурса или еще что-то в этом роде - другое дело. При этом, если обработка неудачного создания всегда одинакова, фабричная функция имеет преимущества - пишешь обработку один раз, а потом только if 0 return - несколько короче, чем try\catch, да еще если неоднократно...



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


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


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

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



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

Разве? ЕМНИП, контейнеры STL по этому поводу не гарантируют уже не помню что, если в конструкторе может выброситься исключение.
Скажем, если я создаю вектор из 10 элементов, и 5-й конструктор выбросил исключение - то в каком состоянии останется контейнер?


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


Архимед
****


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

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



Цитата(JackYF @  9.1.2008,  20:40 Найти цитируемый пост)
то в каком состоянии останется контейнер? 

Его конструктор выкинет исключение(как new T[]).


--------------------
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
Дата 9.1.2008, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(archimed7592 @  9.1.2008,  19:44 Найти цитируемый пост)
Его конструктор выкинет исключение(как new T[]). 

отлично, а кто будет освобождать память из-под 4 элементов, конструкторы которых уже вызвались?


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


Архимед
****


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

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



Цитата(JackYF @  9.1.2008,  20:53 Найти цитируемый пост)
отлично, а кто будет освобождать память из-под 4 элементов, конструкторы которых уже вызвались? 

Ну, во-первых, память выделяется под всё сразу. А, во-вторых, как и в случае new T[], вызовутся деструкторы уже сконструированных элементов в порядке, обратном конструированию, потом освободится память(та что под всё сразу) и, наконец, исключение будет переброшено.


--------------------
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
Дата 9.1.2008, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(archimed7592 @ 9.1.2008,  21:45)
Ну, во-первых, память выделяется под всё сразу. А, во-вторых, как и в случае new T[], вызовутся деструкторы уже сконструированных элементов в порядке, обратном конструированию, потом освободится память(та что под всё сразу) и, наконец, исключение будет переброшено.

Код
#include <iostream>
#include <exception>
#include <vector>
#include <string>

struct Error : public std::exception
{
        Error(const std::string &text) throw() : m_text(text) {}
        ~Error() throw(){}
        const char* what() const throw() {
                return m_text.c_str();
        }
private:
        std::string m_text;
};

class Test
{
        static int counter;
        int cnt;
public:
        Test() {
                cnt = counter;
                if (--counter)
                        throw Error("Error");
        }
        ~Test() {
                std::cout << "Cnt=" << cnt << " destroyed" << std::endl;
                ++counter;
        }
};

int Test::counter = 5;

int main()
{
        try {
                std::vector<Test> test(10);
        } catch(std::exception &e) {
                std::cerr << "Exception: " << e.what() << std::endl;
        }
        return 0;
}
Вывод
Код
$ ./a.out 
Exception: Error
gcc версия 4.1.2 (Gentoo 4.1.2)
Я что-то делаю нетак?
PM   Вверх
JackYF
Дата 9.1.2008, 22:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(archimed7592 @  9.1.2008,  20:45 Найти цитируемый пост)
уже сконструированных элементов в порядке, обратном конструированию

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

Добавлено через 57 секунд
о, bsa, отлично, уже живой пример есть smile


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


Архимед
****


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

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



Цитата(bsa @  9.1.2008,  21:52 Найти цитируемый пост)
Я что-то делаю нетак? 

Угу. Замени if (--counter) на if (!--counter).

Добавлено через 1 минуту и 12 секунд
Цитата(JackYF @  9.1.2008,  22:26 Найти цитируемый пост)
в том-то и дело, что могут не вызваться - конструктор не отработал - мы не имеем право вызывать деструктор.

Так, давай, с чувством, с толком, с расстановкой - чей конструктор не отработал, чей деструктор не имеем право вызвать и т.д. 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   Вверх
nickless
Дата 9.1.2008, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Вот Standard-Library Exception Safety от Страуструпа [pdf, 200kB] как дополнение к его же FAQу


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
bsa
Дата 9.1.2008, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(archimed7592 @ 9.1.2008,  22:28)
Цитата(bsa @  9.1.2008,  21:52 Найти цитируемый пост)
Я что-то делаю нетак? 

Угу. Замени if (--counter) на if (!--counter).

 smile 
Там не только это нужно было исправить.
Код
#include <iostream>
#include <exception>
#include <vector>
#include <string>

struct Error : public std::exception
{
        Error(const std::string &text) throw() : m_text(text) {}
        ~Error() throw(){}
        const char* what() const throw() {
                return m_text.c_str();
        }
private:
        std::string m_text;
};

class Test
{
        static int counter;
        int cnt;
public:
        Test() {
                cnt = counter--;
                if (!counter)
                        throw Error("Error");
                std::cout << "Cnt=" << cnt << " created" << std::endl;
        }
        Test(const Test&) {
                cnt = counter--;
                if (!counter)
                        throw Error("Error");
                std::cout << "Cnt=" << cnt << " created" << std::endl;
        }
        ~Test() {
                std::cout << "Cnt=" << cnt << " destroyed" << std::endl;
                ++counter;
        }
};

int Test::counter = 5;

int main()
{
        try {
                std::vector<Test> test(10);
        } catch(std::exception &e) {
                std::cerr << "Exception: " << e.what() << std::endl;
        }
        return 0;
}
Зато вывод стал таким:
Код
$ ./a.out 
Cnt=5 created
Cnt=4 created
Cnt=3 created
Cnt=2 created
Cnt=4 destroyed
Cnt=3 destroyed
Cnt=2 destroyed
Cnt=5 destroyed
Exception: Error

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


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


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

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



Цитата(archimed7592 @  9.1.2008,  21:28 Найти цитируемый пост)
чей деструктор не имеем право вызвать

итак, пример.
пускай есть класс с двумя динамическими полями. Пускай в конструкторе под них выделяется память. Что будет, если я выброшу исключение после того, как память под первое поле уже выделил, а под второе ещё нет?
1) деструктор вызовется. При попытке освободить память из-под второго поля (там мусор, так как конструктор ничего не успел с ним сделать) - сегфолт.
2) деструктор не вызовется. Память, выделенная под первое поле, останется витать в воздухе.

Ещё варианты?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
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   Вверх
bsa
Дата 10.1.2008, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



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

Тут речь идет о выкидывании исключений наружу. Если обработка осуществляется внутри функции (как конструктора, так и деструктора), то проблем вообще никаких нет.
PM   Вверх
JackYF
Дата 10.1.2008, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



UnrealMan, да, ты нереальный человек smile


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


Архимед
****


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

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



Цитата(UnrealMan @  10.1.2008,  20:18 Найти цитируемый пост)
А дальше ловим его в том же деструкторе и обрабатываем функтором-обработчиком (при этом деструктор не знает, как именно должна происходить обработка исключения).

Как же я сразу не догадался в чём подвох smile.

В принципе, для записи логов и т.п. решение очень даже красивое(тот самый throw; во внешней ф-ции, да? 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   Вверх
baldina
  Дата 10.1.2008, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

1. деструктор вызовется
2. деструктор не вызовется

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

Добавлено через 3 минуты и 1 секунду
ступил - до конца не дочитал  smile

Добавлено через 6 минут и 22 секунды
главного то не написал:
надо бросить - бросаю. 
хотя конечно не ожидая исключений как-то комфортнее
PM MAIL   Вверх
UnrealMan
Дата 10.1.2008, 20:48 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(archimed7592 @  10.1.2008,  20:25 Найти цитируемый пост)
В принципе, для записи логов и т.п. решение очень даже красивое(тот самый throw; во внешней ф-ции, да?  smile. 

Ну, да. Допустим, объект по уничтожении должен сбросить некоторую инфу в файл. Но по какой-то причине запись в файл оказалась невозможной (файл заблокирован, не хватило места на диске). Мы можем попросить пользователя закрыть кое-какие программы или освободить место на диске. Как именно обращаться к пользователю, классу уничтожаемого объекта знать не обязательно, ибо это не его дело. Достаточно, чтобы деструктор откуда-то получил функциональный объект, обрабатывающий исключения (например, он может быть сохранён в объекте при конструировании). При этом возможны две ситуации: объекту-обработчику (при помощи доброго пользователя) удалось разрешить проблему, либо не удалось. Если удалось, мы можем повторить попытку записи в файл. Если не удалось, просто выходим из деструктора (какие-то данные будут потеряны, но такова уж судьба - ничего лучше сделать не смогли).

Описание handler-а и деструктора выглядит примерно так:

Код

struct Handler
{
    void operator ()(параметры)
    {
         try
         {
              throw;
         }
         catch (поехали обрабатывать исключения)
         {
         }
         ....
    }
};

~T()
{
    try
    {
        for (;;)
            try
            {
                ...
            }
            catch (...)
            {
                // handler имеет тип boost::function<void (параметры)>
                handler(параметры); // может бросить исключение в виде объекта класса HandlingFailed
            } // если не бросает, повторяем попытку :-)
    }
    catch (HandlingFailed &)
    {
    }
}

Кстати, конструктор тоже может следовать этой методике. Зачем сразу сдуваться, если можно вежливо попросить пользователя разрешить проблему и доконструроваться себе дальше? smile

Это сообщение отредактировал(а) UnrealMan - 10.1.2008, 21:11
PM MAIL   Вверх
JackYF
Дата 10.1.2008, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



UnrealMan, честно говоря, не понял сиих конструкций.  smile .
При возникновении нештатной ситуации в деструкторе я лучше сделаю запись в логах, что всё плохо или не очень, и выйду из деструктора.


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


Опытный
**


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

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



Цитата(JackYF @  10.1.2008,  21:12 Найти цитируемый пост)
При возникновении нештатной ситуации в деструкторе я лучше сделаю запись в логах, что всё плохо или не очень, и выйду из деструктора.

Зачем так пессимистично поступать? Вдруг нештатную ситуацию удастся разрешить и во вполне штатном режиме выполнить функции деструктора?

Добавлено @ 21:20
Цитата(JackYF @  10.1.2008,  21:12 Найти цитируемый пост)
UnrealMan, честно говоря, не понял сиих конструкций. 

Шо не понятно? Выбросили исключение, поймали, вызвали обработчик, в обработчике исключение сгенерировали повторно и обработали smile

Добавлено @ 21:23
Класс, которому принадлежит деструктор, об обработчике почти ничего не знает - т.е., например, способ обращения к пользователю не будет захардкоден в деструктор, и это есть хорошо smile 

Это сообщение отредактировал(а) UnrealMan - 10.1.2008, 21:24
PM MAIL   Вверх
JackYF
Дата 10.1.2008, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(UnrealMan @  10.1.2008,  20:19 Найти цитируемый пост)
Шо не понятно?

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


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


Архимед
****


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

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



Цитата(JackYF @  10.1.2008,  21:43 Найти цитируемый пост)
Да и вообще - мой мозг на сейчас отказывается воспринимать эту структуру кода.

Запусти:
Код

void f1();
void f2()
{
  try
  { throw 0; }
  catch(...)
  { f1(); }
}

void f1()
{
  try
  { throw; }
  catch(...)
  { std::cout << "hi" << std::endl; }
}



--------------------
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, 22:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(JackYF @  10.1.2008,  21:43 Найти цитируемый пост)
Как эта штука будет масштабироваться на несколько деструкторов.

Тут не стоит такая задача.
Желательно, чтобы обработка исключений и функционал деструктора были разнесены, а не перемешивались (знакомая парадигма, не так ли?). Вот на это данный код и нацелен.
PM MAIL   Вверх
JackYF
Дата 10.1.2008, 22:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(archimed7592 @  10.1.2008,  20:47 Найти цитируемый пост)
try
  { throw; }
  catch(...)

так, уже лучше. Каково предназначение этого куска кода?


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


Опытный
**


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

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



Цитата(JackYF @  10.1.2008,  22:02 Найти цитируемый пост)
так, уже лучше. Каково предназначение этого куска кода? 

Т.к. мы хотим заставить исключения обрабатываться в этих catch-блоках (внутри функции/функтора-обработчика), то исключение надо генерировать внутри соответствующего try-блока. А поскольку изначально исключение генерируется не в этом try-блоке, а в другом месте (где-то в деструкторе), то нужно поймать это исключение и повторно сгенерировать его внутри данного try-блока, а иначе внутрь этого try-блока оно никак не попадёт. Я понятно выражаюсь? smile
PM MAIL   Вверх
archimed7592
Дата 10.1.2008, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


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

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



Цитата(JackYF @  10.1.2008,  22:02 Найти цитируемый пост)
Каково предназначение этого куска кода? 

Эммм, ок, дабы немного придать смысл коду:
Код

void handler();
void foo()
{
  try
  {
      if (std::rand() % 2)
        throw 0;
      else
        throw "0";
  }
  catch(...)
  { handler(); }
}
void handler()
{
  try
  { throw; }
  catch(int i)
  { std::cout << "int = " << i << std::endl; }
  catch(const char *s)
  { std::cout << "string = " << s  << std::endl; }
  catch(...)
  { std::cout << "unknown" << std::endl; }
}



--------------------
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, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Теперь понял, спасибо вам обоим.


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


^аВаТаР^ сообщение>>
****


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

Репутация: 45
Всего: 134



есть мнение что в подобном случае следует заводить ф-цию init и вызывать её, дабы в случае чего деструктор уничтожал объект.
вообще стараюсь исключения не кидать. 
а если кидать то в основном из ASSERT'ов.



--------------------
 Здесь был кролик. Но его убили.
Человеки < кроликов, йа считаю.
PM MAIL WWW ICQ   Вверх
vadiml
Дата 12.1.2008, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: 2
Всего: 7



как писали выше, можно заворачивать вызов конструктора. Правда я для этого не пишу специальную статическую функцию. Такое надо очень редко и хватает обычной функции, которая вернёт указатель или NULL, а далее if ( retval == NULL ) { что-то по этому поводу сделать }. Так же в такую функцию часто добавляю вывод в stderr, что бы сразу это видеть.



Это сообщение отредактировал(а) vadiml - 12.1.2008, 16:14
PM MAIL Jabber   Вверх
chipset
Дата 21.1.2008, 05:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

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



Пишу специальное исключение. Если не сгенерировался обьект то лучше всего убить программу пока не поздно и записать в лог подробности. Допустим на серверах так и делается обычно.

А что-бы избежать ситуации: имеем два обьекта А и Б, А инициализирован, Б нет -- чо делать ё? стараюсь что-бы у каждого обьекта был только один указатель на данные которые он обрабатывает.

Это выглядит вот так:

Код

class IntArray : ReferenceCountedStorage<vector<int> > 
{
/* vector<int> *m_dataPtr; //taken care by RCS */
public:
//функции которые работают с m_dataPtr
};



--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
UnrealMan
Дата 25.1.2008, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(chipset @  21.1.2008,  05:29 Найти цитируемый пост)
А что-бы избежать ситуации: имеем два обьекта А и Б, А инициализирован, Б нет -- чо делать ё?

Использовать smart pointer-ы или try + catch.
PM MAIL   Вверх
Lycifer
Дата 4.8.2008, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Вообще исключения в конструкторах очень опастно
пример
class A
{
public:
      A()
    {
throw 1;
    }
};
class B : A
{
public:
      B()
    {

    }
};

решение проблемы

class A
{
protected:
bool IsCreateBad;
A(bool)
{
}
public:
      A():IsCreateBad(false)
    {
throw 1;
    }
bool getCreateObject()
{
return IsCreateBad;
}
};
class B : A
{
protected:
B(bool isCreateBad) 
    {
    }
public:
      B() try
    {
    }
catch(...)
{
(*this) = B(true);
}
};

Добавлено через 11 минут и 46 секунд
Ну почемуто возникает assert вопрос почему?

PM MAIL ICQ   Вверх
bsa
Дата 4.8.2008, 23:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Lycifer, проблемы нет там, где ты думаешь, что она есть. Так как если конструктор кидает исключение, значит он не смог сконструировать объект класса, значит конструктор потомка не должен даже запускаться.
PM   Вверх
SABROG
Дата 5.8.2008, 00:07 (ссылка) |  (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


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

Репутация: 4
Всего: 91



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

По теме. Исключения почти никогда не использовал, т.к. небыло необходимости. Обычно проблемы решаются достаточно тривиальными проверками на уровне возвращаемого значения true или false. Уж не знаю как вы, а для меня исключения это не более чем int 3 или деление на 0, а остальное от лукавого.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
vinter
Дата 5.8.2008, 07:22 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(SABROG @  5.8.2008,  01:07 Найти цитируемый пост)
Уж не знаю как вы, а для меня исключения это не более чем int 3 или деление на 0, а остальное от лукавого. 
--------------------

значит ты просто не понимаешь исключений.



--------------------
Мой блог
PM MAIL WWW   Вверх
W4FhLF
Дата 5.8.2008, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


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

Репутация: 20
Всего: 121



Цитата(SABROG @  5.8.2008,  00:07 Найти цитируемый пост)
 Исключения почти никогда не использовал, т.к. небыло необходимости.


Это тебя не красит. smile 

Почитай Exception vs Error Code


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Lycifer
Дата 5.8.2008, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

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

А потом оброщение к не существующей памяти, или try и catch где объект создаётся ставить?(Лучше это сделать в класе вот только не получилось  smile ,почему не могу понять)
PM MAIL ICQ   Вверх
vinter
Дата 5.8.2008, 10:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(Lycifer @  5.8.2008,  10:49 Найти цитируемый пост)
А потом оброщение к не существующей памяти, или try и catch где объект создаётся ставить?

без try\catch будет вызван termination(); и программа упадет.


--------------------
Мой блог
PM MAIL WWW   Вверх
Partizan
Дата 5.8.2008, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Let's do some .NET
****


Профиль
Группа: Модератор
Сообщений: 2828
Регистрация: 19.12.2005
Где: Санкт-Петербург

Репутация: 4
Всего: 67



Кстати говоря, двухфазные конструкторы в Symbian решают аналогичные проблемы...


--------------------
СУВ,
       Partizan.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Torsten
Дата 5.8.2008, 11:27 (ссылка)  | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: 3
Всего: 7



Цитата
стараюсь не бросать исключений в конструкторах, но иногда приходится

хотя в основном, практически всегда создаю метод Init, где и произвожу все сложную инициализацию, которая может привести к проблемам.
Вообще исключение не люблю, код от них бухнет и его трудно читать, поэтому стараюсь их всегда избегать.

Это сообщение отредактировал(а) Torsten - 5.8.2008, 11:28
--------------------
We have no begining, we have no end. We are infinite.
PM MAIL   Вверх
Lazin
Дата 5.8.2008, 11:39 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Torsten @  5.8.2008,  11:27 Найти цитируемый пост)
Вообще исключение не люблю, код от них бухнет и его трудно читать, поэтому стараюсь их всегда избегать.

еще один пациент smile 
PM MAIL Skype GTalk   Вверх
Lycifer
Дата 5.8.2008, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата

без try\catch будет вызван termination(); и программа упадет. 
 - и это хорошо?
PM MAIL ICQ   Вверх
Peter
Дата 5.8.2008, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

Репутация: -1
Всего: 1



Цитата(Mayk @  11.1.2008,  20:14 Найти цитируемый пост)
есть мнение что в подобном случае следует заводить ф-цию init и вызывать её, дабы в случае чего деструктор уничтожал объект

Цитата(Torsten @  5.8.2008,  11:27 Найти цитируемый пост)
хотя в основном, практически всегда создаю метод Init, где и произвожу все сложную инициализацию, которая может привести к проблемам

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



--------------------
всё, что делаете, делайте от души, как для Господа (Послание апостола Павла колоссянам, 3:23).
PM MAIL WWW   Вверх
UnrealMan
Дата 5.8.2008, 14:16 (ссылка) |   (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Lycifer @  5.8.2008,  12:41 Найти цитируемый пост)
- и это хорошо?

Это хорошо.

А вот создавать невалидный объект и потом его инициализировать, притом не допуская иного способа инициализации объекта - это определённо нехорошо.
PM MAIL   Вверх
Torsten
Дата 5.8.2008, 16:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

Репутация: 3
Всего: 7



Цитата(Lazin @  5.8.2008,  11:39 Найти цитируемый пост)
еще один пациент  

а чего это я больным стал ?

--------------------
We have no begining, we have no end. We are infinite.
PM MAIL   Вверх
vinter
Дата 5.8.2008, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Цитата(Torsten @  5.8.2008,  17:14 Найти цитируемый пост)
а чего это я больным стал ?

паническая болезнь исключений smile


--------------------
Мой блог
PM MAIL WWW   Вверх
Lazin
Дата 5.8.2008, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Torsten @  5.8.2008,  16:14 Найти цитируемый пост)
а чего это я больным стал ?

будем тебя учить любить исключения smile 
PM MAIL Skype GTalk   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1390 ]   [ Использовано запросов: 24 ]   [ GZIP включён ]


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

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