Форум программистов, компьютерный форум CyberForum.ru

Обработка неудачного вызова конструктора класса - C++

Восстановить пароль Регистрация
 
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 405
08.03.2014, 08:41     Обработка неудачного вызова конструктора класса #1
Есть ли в С++ средства обработки неудачного вызова конструктора класса.
т.е. самый простой типовой вызов конструктора класса имеет вид
C++
1
graph *g=new graph(6,7,E);
Можно ли из него понять создан ли объект g или нет ?

Применение этого например, такое - создание конструктора графа, берущего его параметры из файла
В случае неудачного формата файла конструктор должен (если возможно) отказаться от создания экземпляра класса.
Конечно, можно видимо запихнуть процедуру чтения файла в конструктор и ничего внутри него не делать
а при вызове проверить на NULL
C++
1
2
3
4
graph *g=new graph(6,7,E);
 if(g==NULL) {
 //обработка события неудачного создания экземпляра класса
                  };
Есть видимо и другое решение. Создать статический метод класса - чтения из файла.
возвращающий также успех (true) или неудачу (false). И до создания объекта класса вызвать его
и в зависимости от того что вернет вызывать или нет конструктор
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
08.03.2014, 08:51     Обработка неудачного вызова конструктора класса #2
Цитата Сообщение от eugrita Посмотреть сообщение
Можно ли из него понять создан ли объект g или нет ?
Читаем про оператор new, смотрим какие исключения он бросает http://en.cppreference.com/w/cpp/mem...w/operator_new

Цитата Сообщение от eugrita Посмотреть сообщение
Применение этого например, такое - создание конструктора графа, берущего его параметры из файла
В случае неудачного формата файла конструктор должен (если возможно) отказаться от создания экземпляра класса.
Можно кинуть исключение. Но тут надо помнить, что если из конструктора кидается исключение, то деструктор вызван не будет, что может привести к утечкам памяти.

Цитата Сообщение от eugrita Посмотреть сообщение
Создать статический метод класса - чтения из файла.
возвращающий также успех (true) или неудачу (false).
Пусть он лучше сразу возвращает либо указатель на объект, либо NULL. Где гарантия, что вы будете создавать объект с теми же параметрами, которые уже проверили на корректность?
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 405
09.03.2014, 03:37  [ТС]     Обработка неудачного вызова конструктора класса #3
Очень не люблю обрабатывать исключения. Мой опыт показывает, что если они возникают, программа кроме реакции по написанному обработчику, выдает еще стандартное системное сообщение - неприятно.
В поднятом вопросе о конструкторе графа по данным из файла вижу такой вариант
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
graph::graph(char * fln,bool * p)
 {//загрузка графа из файла
   FILE * f=fopen(fln,"r");
   if (f==NULL) {*p=false;return;}
  // чтение графа из файла
 //добавление ребер по данным файла
  while (!eof(f) {
  if(...)  //если ошибка чтения начальной или конечной вершины
 {*p=false;return;}
   ....
                    };
   *p=true;
 }
...
void main()
{...
bool B;
graph *g=new graph("dan.txt",B);
if (!B) //неудачный вызов
{delete g; return;};
DU
1477 / 1053 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
09.03.2014, 03:53     Обработка неудачного вызова конструктора класса #4
не любите исключения наверно потому что не умеете их готовить.
из конструктора можно таким макаром вернуть флаг конечно. но
объект должен оставаться в корректном согласованном состоянии.
и чтобы его проверять у него должен быть соответствующий интерфейс,
т.е. методы, через которые можно понять что он валидный\невалидный.
еще в таких случаях часто используют так называемое двух фазное
конструирование. это конструктор, который ничего не бросает,
и метод инициализации, который возвращает какой-нибудь флажок или ошибку.

в вашем последнем примере теоретически new может бросить исключение,
хотя на практике это редкий кейс.
0x10
2425 / 1597 / 232
Регистрация: 24.11.2012
Сообщений: 3,919
09.03.2014, 06:54     Обработка неудачного вызова конструктора класса #5
Цитата Сообщение от DU Посмотреть сообщение
еще в таких случаях часто используют так называемое двух фазное
конструирование. это конструктор, который ничего не бросает,
и метод инициализации, который возвращает какой-нибудь флажок или ошибку.
Можно, конечно, но проблема понятная: такой класс предполагает определенный порядок вызова методов и между ними находится в каком-то непонятном состоянии.

Цитата Сообщение от eugrita Посмотреть сообщение
Мой опыт показывает, что если они возникают, программа кроме реакции по написанному обработчику, выдает еще стандартное системное сообщение - неприятно.
Чет фигня какая-то... Не верю я, что разработчики компиляторов настолько тупые, чтобы навязывать подобное поведение. Другое дело, если вы запускаете отладочную сборку, где могут быть свои обработчики исключений. Или если в среде настроены хуки на перехват всех бросаемых исключений. Тогда ок.
В релизной сборке не происходит ничего лишнего.

Если не нравится идея написать отдельную функцию, которая возвращает либо указатель на объект, либо nullptr. Можно завести отдельный класс GraphReader, который будет отвечать за чтение графа из файла. Аналогично JsonReader'у тут: http://jsoncpp.sourceforge.net/
Yandex
Объявления
09.03.2014, 06:54     Обработка неудачного вызова конструктора класса
Ответ Создать тему
Опции темы

Текущее время: 12:10. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru