Может кто знает. есть класс допустим A есть код A *a; a=new A() если в конструкторе A произошла ошибка, ну допустим при открытии файла, вообщем произошло условие при котором объект а недействительный Возможно ли, чтобы оператор new в таком случае вернул NULL ?
По идее должен стрелять исключением. А то произойдет обращение по адресу NULL и вот Вам segmentation fault...
Дык в чем проблема-то? void* operator new (size_t size) { try { return ::new MyClass(); } catch (...) { return NULL; } }
panda-34, так то так, но тогда возникает резонный вопрос - зачем? В дальнейшем обязательно придется проверять указатель на NULL, и обрабатывать эту ситуацию - так не проще сразу перехватить эксепшн и обработать?
sp_r00t, Неправильно. Вопрос должен у Бульёна возникать. А я ответ даю. Иногда приходится делать вещи, которые для знающих людей являются полным бредом. Но приходится. И всегда, вместо того, чтобы просто дать четкий ответ на четкий вопрос, начинается рассусоливание: да это все не так, да это все по другому надо делать. И exception далеко не всегда проще перехватить и обработать. Я, вот, последний раз писал на C++ для микроконтроллера, там даже от конструкторов пришлось отказаться и сделать свою "фабрику объектов" на статической функции, т.к. конструктор увеличивал размер прошивки аж на 4 килобайта и расходовал херову кучу RAM.
Я понимаю Собственно мой вопрос правильнее было бы топикстартеру адресовать - ну вот любопытно стало, для чего такой замут?
Лучше не пихать в конструктор ошибкогенерящий код. И тогда вопросы подобные этому просто не возникают.
чтобы не разносить код для создания объекта по разным функциям, ну например A *a; BOOL bRet; a=new A(); if (a!=NULL) bRet=a->Init(prm); if (bRet!=FALSE) { //объект создан } ---------- Сообщение добавлено 12.10.2010 20:40 ---------- к сожалению он весь такой ну разве a=0; //всегда будет работать
А больше в конструктор ничего и не нужно класть. Вот это как раз гораздо надежнее гемора с кастомными new, исключениями и прочими радостями типа наполовину отработавшего конструктора из 1000 строк. Особенно, если сделать конструктор защищенным и сложить все эти строчки в статическую функцию-фабрику - тогда абсолютно все экземпляры будут создаваться в одном единственном месте.
Очень просто. Если в конструкторе только инициализируются переменные и ничего более, то смысла кастомизировать new нет. И без исключений можно обойтись (я обхожусь), либо все их легко локализовать в фабрике. Лично я пользуюсь конструкциями типа: Код: [/FONT] [FONT=Courier New]class CMyClass[/FONT] [FONT=Courier New]{[/FONT] [FONT=Courier New]protected:[/FONT] [FONT=Courier New]FILE* m_pFile; [INDENT]CMyClass(void) [/INDENT][/FONT] [INDENT][FONT=Courier New]:m_pFile(NULL)[/FONT] [FONT=Courier New]{[/FONT] [FONT=Courier New]}[/FONT] [/INDENT][FONT=Courier New]virtual int Init(char* pcFileName)[/FONT] [FONT=Courier New]{//функция на 1000 строк.[/FONT] [INDENT][FONT=Courier New]m_pFile = fopen(pcFileName, "r");[/FONT] [FONT=Courier New]//todo: остальные 990 строк...[/FONT] [FONT=Courier New]return (m_pFile!=NULL);[/FONT] [/INDENT][FONT=Courier New]}[/FONT] [FONT=Courier New]public:[/FONT] [FONT=Courier New]virtual ~CMyClass()[/FONT] [FONT=Courier New]{[/FONT] [INDENT][FONT=Courier New]Close();[/FONT] [/INDENT][FONT=Courier New]}[/FONT] [FONT=Courier New]virtual void Close()[/FONT] [FONT=Courier New]{[/FONT] [INDENT][FONT=Courier New]if(m_pFile)[/FONT] [INDENT][FONT=Courier New]{ fclose(m_pFile);m_pFile=NULL;}[/FONT] [/INDENT][/INDENT][FONT=Courier New]}[/FONT] [FONT=Courier New]static CMyClass* CreateInstance(char* pcFileName)[/FONT] [FONT=Courier New]{[/FONT] [INDENT][FONT=Courier New]int r;[/FONT] [FONT=Courier New]CMyClass* pInstance = new CMyClass();[/FONT] [FONT=Courier New]try[/FONT] [FONT=Courier New]{[/FONT] [INDENT][FONT=Courier New]r = pInstance->Init(pcFileName);[/FONT] [/INDENT][FONT=Courier New]}[/FONT] [FONT=Courier New]catch(...)[/FONT] [FONT=Courier New]{[/FONT] [INDENT][FONT=Courier New]r=0;[/FONT] [/INDENT][FONT=Courier New]}[/FONT] [FONT=Courier New]if(!r)[/FONT] [FONT=Courier New]{//наша фабрика работает по принципу "все или ничего"[/FONT] [INDENT][FONT=Courier New]//если инициализация обломалась, то херим объект и ничего наружу не отдаем:[/FONT] [FONT=Courier New]delete pInstance;[/FONT] [FONT=Courier New]pInstance = NULL;[/FONT] [/INDENT][FONT=Courier New]}[/FONT] [FONT=Courier New]return pInstance;[/FONT] [FONT=Courier New]}[/FONT] [/INDENT][FONT=Courier New]};[/FONT] [FONT=Courier New]int main(int argc, char* argv[])[/FONT] [FONT=Courier New]{[/FONT] [INDENT][FONT=Courier New]CMyClass* pClass = CMyClass::CreateInstance("c:\\readme.txt");[/FONT] [FONT=Courier New]if(!pClass)[/FONT] [FONT=Courier New]{[/FONT] [FONT=Courier New]printf("какая-то беда с созданием экземпляра CMyClass\n");[/FONT] [FONT=Courier New]return -1;[/FONT] [FONT=Courier New]}[/FONT] [FONT=Courier New]//todo: что-то полезное.[/FONT] [FONT=Courier New]return 0;[/FONT] [/INDENT][FONT=Courier New]}[/FONT] [FONT=Courier New]
panda-34, Недавно сильно ковырял SMF - там код в стиле бейсика с goto. И оправдание как у вас: "Но приходится." Ктулху с Исусом заставляют? А смысл конструктору иметь более десятка-другого строк? Не проще ли сразу нормально писать?