LINUX.ORG.RU

Исключения в конструкторе


0

0

У меня проблема: Есть класс Bolvan: class Bolvan { private: char* device; /*и т.д.*/ protected: int sg_fd; public: struct FDError { const char* message; FDError (const char* p) { message = p; } }; Bolvan (char* io_device); ~Bolvan (); /*****И т.д.*****/

};

И у него есть конструктор: Bolvan::Bolvan (char* io_device) {

sg_fd = open (io_device, O_RDONLY); if (sg_fd < 0) { char *msg; sprintf (msg, "Unable to open device %s\n", io_device); #ifdef DEBUG sprintf (msg, "open (io_device, O_RDONLY) failed. \n Maybe device name is not valid.\n Check open() call in bolvan.cpp\n"); #endif throw FDError ((const char*)msg); } /***** И т.д. и т.п. */ }

Я в main задаю девайс и перехватываю исключение: int main (int argc, char* argv[]) { try { Bolvan CB ("/dev/hdc"); } catch (Bolvan::FDError e) { std::cerr << "File Descriptor error: " << e.message; return 1; } /******и т.д.***/ }

Так вот, при комиляции мне g++ пишет, что ФУНКЦИЯ CB НЕ ОПРЕДЕЛЕНА! Я пробовал Bolvan CB = Bolvan ("/dev/hdc");. Тот же результат Если исключение не перехватывать (убрать try & catch), то все работает. У Бьерна написано, что можно таким макаром перехватывать исключения из конструкторов. P.S.: Все нужные хидеры включены. P.P.S.:Заранее спасибо. Надеюсь на Ваш квалифицированны ответ

anonymous

У меня проблема:
Есть класс Bolvan:
class Bolvan {
private:
char* device;
/*и т.д.*/
protected:
int sg_fd;
public:
struct FDError {
const char* message;
FDError (const char* p) { message = p; }
};
Bolvan (char* io_device);
~Bolvan ();
/*****И т.д.*****/

};

И у него есть конструктор:
Bolvan::Bolvan (char* io_device) {

sg_fd = open (io_device, O_RDONLY);
if (sg_fd < 0) {
char *msg;
sprintf (msg, "Unable to open device %s\n", io_device);
#ifdef DEBUG
sprintf (msg, "open (io_device, O_RDONLY) failed. \n Maybe device name is not valid.\n Check open() call in bolvan.cpp\n");
#endif
throw FDError ((const char*)msg);
}
/***** И т.д. и т.п. */
}

Я в main задаю девайс и перехватываю исключение:
int main (int argc, char* argv[])
{
try {
Bolvan CB ("/dev/hdc");
}
catch (Bolvan::FDError e) {
std::cerr << "File Descriptor error: " << e.message;
return 1;
}
/******и т.д.***/
}

Так вот, при комиляции мне g++ пишет, что ФУНКЦИЯ CB НЕ ОПРЕДЕЛЕНА! Я пробовал Bolvan CB = Bolvan ("/dev/hdc");. Тот же результат Если исключение не перехватывать (убрать try & catch), то все работает. У Бьерна написано, что можно таким макаром перехватывать исключения из конструкторов. P.S.: Все нужные хидеры включены. P.P.S.:Заранее спасибо. Надеюсь на Ваш квалифицированны ответ

anonymous
()
Ответ на: комментарий от anonymous

alex@alex:~> gcc -v
Reading specs from /usr/lib/gcc-lib/i486-suse-linux/3.2/specs
Configured with: ../configure --enable-threads=posix --prefix=/usr
--with-local-prefix=/usr/local --infodir=/usr/share/info
--mandir=/usr/share/man --libdir=/usr/lib
--enable-languages=c,c++,f77,objc,java,ada --enable-libgcj
--with-gxx-include-dir=/usr/include/g++ --with-slibdir=/lib
--with-system-zlib --enable-shared --enable-__cxa_atexit i486-suse-linux
Thread model: posix
gcc version 3.2

Все компилится.

asd
()
Ответ на: комментарий от asd

Странно. У меня не компилится. Хотя может попробовать пересобрать g++ ? А то я его не ставил, он ставился вместе с дистром и я его не трогал и не обновлял.

anonymous
()
Ответ на: комментарий от anonymous

Посмотри на какую именно строку ругается компиллер,
скорее всего он ругается после закрытия
try - у тебя переменная CB видна только внутри try после (и даже внутри catch) ее не видно когда ты трай убераеш ее видно во всем маине, а у gcc есть болезнь все неизвестные имена обзывать функциями.

zaz ★★★★
()

Да и еще - исключения в кострукторе очень опасная весч! и пользовать ее без крайней надобности не рекомендуется т.к. если ты получаеш исключение в конструкторе то деструктор для объекта не вызывается - хотя все мемберы разрушаются коректно - это не баг гцц это так у Страуструпа написано!
Правда возникает вопрос что если эксепшен произашел в мемберском объекте, или что будет с предками ?
В общем лутше всю инициализацию винести скажем в инит и его руками дергать.

zaz ★★★★
()
Ответ на: комментарий от zaz

> Да и еще - исключения в кострукторе очень опасная весч! и пользовать ее без крайней надобности не рекомендуется

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

> лутше всю инициализацию винести скажем в инит

Инициализация должна происходить в конструкторе, для этого он и предназначен.

Волнующая тебя проблема вызова деструкторов полей класса прекрасно решается использованием умных указателей.

abbr
()
Ответ на: комментарий от abbr

>Волнующая тебя проблема вызова деструкторов полей класса
>прекрасно решается использованием умных указателей

А я их и использую :) :
template <class T, class ClearMethod = DeleteObject<T> >
class Pointer
{
private:
T* obj;
.....

, только вот у Cтрауструпа написано что конструкторы перегружать нельзя.
Главное не переусердствовать а то например в MFC там уж слишком конструкторы разгрузили :)))
Я сдесь имел ввиду что не стоит в конструкторе делать сложных операций (например открытие файла)

zaz ★★★★
()
Ответ на: комментарий от anonymous

ТАк как же мне вызвать конструктор ВНЕ блока try, если мне нужно перехватывать исключения из него?

anonymous
()
Ответ на: комментарий от anonymous

>Ак как же мне вызвать конструктор ВНЕ блока try, если мне
>нужно перехватывать исключения из него?

А никак - можно правда работать через указатели но это уже бред т.к. если у тебя в конструкторе произашел ексепшен то объект не создается.
Тебе такого делать не надо просто перенеси весь код в котором используется объект внутрь try и все.

zaz ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.