Russian Qt Forum

Программирование => С/C++ => Тема начата: ZIkos от Март 07, 2008, 13:10



Название: Как убить самого себя если при создании что то пошло не так?
Отправлено: ZIkos от Март 07, 2008, 13:10
Есть класс
class CClass1:
{
public:
  CClass1();
  virtual ~CClass1();
private:
  bool Start();
};

CClass1::CClass1()
{
  if(Start() == false)
    return;
}

bool CClass1::Start()
{
return false;
}

Второй класс
class CClass2:
{
public:
  CClass2();

private:
  void Exec();
private:
  CClass1*  class1;
};

CClass2::CClass2()
{
 class1 = 0;
}

void CClass2::Exec()
{
 bool f = true;
 class1 = new CClass1();
 if(class1 == 0)
    f = false;
}

Вопрос собственно такой. При выходе из конструктора с помощью return объект все равно создается. Как выйти из положения?


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: uriel от Март 07, 2008, 22:19
За название темы - зачёт. :)
Теперь по делу. Никак. Если ты выделил память под объект, то он в любом случае будет создан, что бы не произошло при создании (условно).
Точно не уверен, но можешь попробовать переопределить оператор new для класса и в нём проверять то, что требуется.
А вообще, проще пересмотреть саму идею программы, ибо эта какая-то кривая. :)


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: vregess от Март 08, 2008, 08:19
 ;D  :) :) :) :) как тебе удалось придумать такую тему поста?? )
имхо не надо ничего переопределять.. попробуй вынести условия из CClass1::Start() за пределы класса, например в CClass2:
Код:
void CClass2::Exec()
{
 if(canCreateC1())
   class1 = new CClass1();
}
ну или что-то подобное


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: uriel от Март 08, 2008, 09:39
Просто, как я понял, у него там после создания идёт проверка, был ли класс создан.
Можно, кстати, сделать фабричный метод. То есть, если всё хорошо, то он возвращает указатель на созданный объект класса, если нет - то 0.


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: ZIkos от Март 08, 2008, 11:49
Просто, как я понял, у него там после создания идёт проверка, был ли класс создан.
Можно, кстати, сделать фабричный метод. То есть, если всё хорошо, то он возвращает указатель на созданный объект класса, если нет - то 0.

Название темы придумал на ходу  ;)

Да все правильно. В функции Start класса1 я тоже выполняю кое-какие действия. И в результате возвращаеться true или false в конструктор этого класса. И если возвращаеться false то экземпляр класса не должен быть создан. Вынести условие проверки в класс2 нельзя. Что такой за фабричный метод? Буду очень благодарен за пример.


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: Tonal от Март 08, 2008, 15:51
Вообще-то классическое решение для С++ - выкинуть исключение.
При этом вызовутся деструкторы всех созданных членов данных и освободиться память, если экземпляр создавался по new.
Остальные решения - а-ля MFC для "С с классами". :-)


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: uriel от Март 08, 2008, 16:46
Но сама Qt, почему-то, их не кидает. :) Кроме того, так и не получилось заставить приложение ловить классы исключений, описанные в подключаемых библиотеках (но это уже мои косяки, думается).
Самый простой вариант в данном случае - примерно такой.
Код:
class CClass1
{
...
static CClass1 *getInstance();
...
};

CClass1 *CClass1::getInstance()
{
 ...
 if (ok)
  return new CClass1;
 else
  return 0;
}
Но в данном виде это будет работать только если те действия, корректность которых надо проверить, не изменяют внутреннюю структуру класса.


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: Tonal от Март 09, 2008, 11:02
Но сама Qt, почему-то, их не кидает. :)
Это потому, что многие, после прочтения древних книжек, не верят в исключения (как та бабушка, которая не верила в электричество) и отрубают их поддержку. :)


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: learn от Июнь 01, 2008, 23:47
Tonal прав.
Если конструктор выкидывает исключение, объект не создается.

if(start() != true) throw...

а уже выше его ловишь и обрабатываешь,

но в случае с синглтоном вроде другая ситуация, если ты о нем.


Название: Re: Как убить самого себя если при создании что то пошло не так?
Отправлено: ритт от Август 03, 2008, 14:14
и всё-равно это криво - хоть с ислючением, хоть без
предпочитаю абстрактный класс, наследник-заглушка, наследник рабочий, д-указатель и метод init()