Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 451
#1

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

08.03.2014, 08:41. Просмотров 415. Ответов 4
Метки нет (Все метки)

Есть ли в С++ средства обработки неудачного вызова конструктора класса.
т.е. самый простой типовой вызов конструктора класса имеет вид
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). И до создания объекта класса вызвать его
и в зависимости от того что вернет вызывать или нет конструктор
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
08.03.2014, 08:41
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Обработка неудачного вызова конструктора класса (C++):

Различные по синтаксису способы вызова конструктора - C++
Даже не знаю, как правильно задать вопрос, проще разобрать на примере. Пусть есть функция void func(const T1 &o1, const T2 &o2,...

Выделение памяти под массив объектов без вызова конструктора - C++
Добрый вечер. Насколько я знаю, при выделении памяти под массив объектов, для каждого из них вызывается конструктор. Можно ли сперва...

Вызов конструктора базового класса из класса-наследника - C++
Можно ли вне списка инициализации вызвать конструктор базового класса ? class A { int a; public: A(int c):a(c){} ...

Реализация конструктора класса - C++
Здравствуйте! Хотел задать такой вопрос: Предположим, имеется класс: class Object { private: int itsVal1; int...

Вызов конструктора класса - C++
есть класс Set, и в нем есть конструктор, как с этого конструктора мне массивы перенести в метод другого класса так что бы над ними можно...

Смысл конструктора класса - C++
Добрый день! Потихоньку начинаю программировать на С++ и разибраться в чужом коде. Все бы ничего, но наткнулся на класс class MElement...

4
0x10
2482 / 1657 / 249
Регистрация: 24.11.2012
Сообщений: 4,126
08.03.2014, 08:51 #2
Цитата Сообщение от eugrita Посмотреть сообщение
Можно ли из него понять создан ли объект g или нет ?
Читаем про оператор new, смотрим какие исключения он бросает http://en.cppreference.com/w/cpp/memory/new/operator_new

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

Цитата Сообщение от eugrita Посмотреть сообщение
Создать статический метод класса - чтения из файла.
возвращающий также успех (true) или неудачу (false).
Пусть он лучше сразу возвращает либо указатель на объект, либо NULL. Где гарантия, что вы будете создавать объект с теми же параметрами, которые уже проверили на корректность?
0
eugrita
3 / 4 / 0
Регистрация: 18.11.2009
Сообщений: 451
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;};
0
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
09.03.2014, 03:53 #4
не любите исключения наверно потому что не умеете их готовить.
из конструктора можно таким макаром вернуть флаг конечно. но
объект должен оставаться в корректном согласованном состоянии.
и чтобы его проверять у него должен быть соответствующий интерфейс,
т.е. методы, через которые можно понять что он валидный\невалидный.
еще в таких случаях часто используют так называемое двух фазное
конструирование. это конструктор, который ничего не бросает,
и метод инициализации, который возвращает какой-нибудь флажок или ошибку.

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

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

Если не нравится идея написать отдельную функцию, которая возвращает либо указатель на объект, либо nullptr. Можно завести отдельный класс GraphReader, который будет отвечать за чтение графа из файла. Аналогично JsonReader'у тут: http://jsoncpp.sourceforge.net/
0
09.03.2014, 06:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.03.2014, 06:54
Привет! Вот еще темы с ответами:

инициализация конструктора класса - C++
инициализация конструктора класса Rectangle::Rectangle(int w, int h): itsWidth(w), itsHeight(h) {} Изучаю с++. объясните...

Обработка исключений в списке инициализации конструктора - C++
Доброго времени суток. Имеем код: #include <iostream> #include "windows.h" #include <fstream> using namespace std; class...

Очерёдность вызова конструкторов класса - C++
У меня есть 2 класса, к примеру Base и Mod. Mod является наследником Base. Классу Mod соответствует такой конструктор: Mod(int _id, int...

Наследование конструктора из базового класса - C++
#include "stdafx.h" #include <iostream> #include <cstring> using namespace std; //////////////////// class String { ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.