DerSpieler
Гость
|
|
« : 03-05-2004 19:46 » |
|
1. В чем разница между virtual void MethodName(); и virtual void MethodName() = 0;
2. Как пользоваться try {} catch() {} и ключевым словом __except?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #1 : 03-05-2004 20:16 » |
|
virtual void MethodName() = 0; означает, что это "чисто" виртуальная функция -pure virtual. Она должна быть переписана в производном классе, а в родительском классе она только объявлена. Обычно это делают для исключения ошибки вызова стандартной версии функции или в интерфейсных классах, содержащих такие функции. Компилятор просто не пропустит производный класс если у в нём не переписана такая функция. Так же невозможно создать объект родительского класса если в нём есть хотя бы одна такая функция. 2. Коротеько - Попробуй вот такой код int p = 0; int a = 1/p; printf("error");
а потом такой try { int p = 0; int a = 1/p; } catch(...) { printf("error"); }
Те try-catch позволяю тебе отловить исключеия, без того что программа вылетит. Обычно в эти скобки берутся "слабые" участки, где невозможно предсказать поведение пользователя или программы. А вообще инфы очень много - так что придётся брать вумную книжку и читать.
|
|
« Последнее редактирование: 25-11-2007 20:04 от Алексей1153++ »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Xeysan
Гость
|
|
« Ответ #2 : 03-05-2004 21:04 » |
|
__except же относиться к программированию в Win32 ( SEH ) На сайте есть книга Рихтера Programming Applications for MS Windows, все ответы в ней.
|
|
|
Записан
|
|
|
|
NetRaider
Гость
|
|
« Ответ #3 : 03-05-2004 23:17 » |
|
...Она должна быть переписана в производном классе ... Это необходимо только в том случае, если будут создоваться объекты этого класса. struct A { virtual void foo() = 0; };
struct B : public A { // foo не объявлена, но это не является ошибкой до тех пор // пока не будет попытки создать экземпляр этого класса };
struct C : public B { void foo(){ } };
int main() { A a; // ошибка B b; // ошибка C c; // ok }
|
|
« Последнее редактирование: 25-11-2007 20:05 от Алексей1153++ »
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #4 : 04-05-2004 05:00 » |
|
Джон, virtual void MethodName() = 0;
а к какому боку тута ноль? Присвоение указателю на функцию?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #5 : 04-05-2004 08:00 » |
|
Алексей1153, Это объявление pure virtual function. Посмотри Страуструпа главу про абстрактные классы.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
DerSpieler
Гость
|
|
« Ответ #6 : 04-05-2004 08:17 » |
|
А как же быть с virtual void MethodName(); :?:
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #7 : 04-05-2004 09:06 » |
|
Это просто виртуальная функция, её можно переопределить в производных классах
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #8 : 04-05-2004 09:26 » |
|
А это просто виртуальная функция, которая может быть определена и в базовом классе. А в производном не обязана. class A1 { public: virtual void MethodName() { printf("Virtual from base class"); } };
class A2 { public: virtual void MethodName() = 0; };
class B1 : public A1 { public: void MethodName() { printf("Virtual from child class"); } };
class B2 : public A2 { public: void MethodName() { printf("Virtual from child class only"); } };
class C1 : public A1 { public: };
class C2 : public A2 { public: };
int main() { A1 a1; // ok - функция объявлена и определена A2 a2; // ошибка - нельзя создать объект абстрактного класса - ф-я не определена B1 b1; // ok простая виртуальная функция переписана - она и будет вызвана B2 b2; // ok - чисто виртуальная функция переписана C1 c1; // ok - будет вызвана функция базового класса C2 c2; // ошибка - нельзя создать объект абстрактного класса }
Кстати, NetRaider, меня совершенно правильно поправил. Спасибо.
|
|
« Последнее редактирование: 25-11-2007 20:07 от Алексей1153++ »
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Diletant
Помогающий
Offline
|
|
« Ответ #9 : 04-05-2004 14:05 » |
|
2. Как пользоваться try {} catch() {} и ключевым словом __except?
__except используется с ключевыми словами __try и при желании __finally. И все это придумано Микрософт IMHO для того, чтобы конструкцию подобную try ... catch() можно было использовать в чистом С. Ну или в почти чистом
|
|
|
Записан
|
|
|
|
DerSpieler
Гость
|
|
« Ответ #10 : 04-05-2004 16:57 » |
|
Спасибо за разъяснения по 1-му вопросу. А на счет второго: :?: Джон, твой пример try { int p = 0; int a = 1/p; } catch(...) { printf("error"); } у меня не работает. Программа вылетает, не обращая внимания на catch. Вот меня и интересует КАК ЖЕ ЭТО ТАК?
|
|
|
Записан
|
|
|
|
Serega
Гость
|
|
« Ответ #11 : 04-05-2004 18:33 » |
|
Какой у тебя компилятор ?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #12 : 04-05-2004 18:42 » |
|
DerSpieler, Да, в какой среде программируешь? И что значит вылетает? Ты видишь ошибку деления на 0 или ничего не происходит?
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
DerSpieler
Гость
|
|
« Ответ #13 : 05-05-2004 08:23 » |
|
Borland C++ Builder 5. Вообще у меня такая проблема: Делаю пакет программ и библиотек для САПР. Есть 2 библиотеки в одной реализован интерфейс, в другой - математика. Из интерфейсной библиотеки вызываю функции математической библиотеки. Там иногда происходит деление на 0. try {} catch () {} не помогает - как только дело доходит до деления на 0, выдается сообщение об этом, функция дальше не выполняется, блок catch остается не при делах. :?
Щас попробовал делить на 0 в оконном приложении - try catch работают как надо. А тогда пробовал в консольном - там ни хрена.
А что еще можно написать в скобках у catch'а?
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #14 : 05-05-2004 08:37 » |
|
Borland C++ Builder 5. Вот тут не попадаем. У меня только VS. Придётся тебе борландцев подождать. А что еще можно написать в скобках у catch'а? Обычно обрабатывается ситуация. Если например исключение было вызвано throw, то она в качестве параметра может передать какой нить объект, содержащий описание ошибки. тогда используется целая серия catch. Для каждого исключения. Ну а написать можно - в зависимости от ситуации, сообщение об ошибке, завершение проги и тд.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
Anonymous
Гость
|
|
« Ответ #15 : 05-05-2004 21:29 » |
|
Borland C++ Builder 5. Вообще у меня такая проблема: Делаю пакет программ и библиотек для САПР. Есть 2 библиотеки в одной реализован интерфейс, в другой - математика. Из интерфейсной библиотеки вызываю функции математической библиотеки. Там иногда происходит деление на 0. try {} catch () {} не помогает - как только дело доходит до деления на 0, выдается сообщение об этом, функция дальше не выполняется, блок catch остается не при делах. :?
Щас попробовал делить на 0 в оконном приложении - try catch работают как надо. А тогда пробовал в консольном - там ни хрена.
А что еще можно написать в скобках у catch'а? Структурная обработка исключений (с помощью __try ... __except) поможет в любом случае. Это обработка исключений на уровне процесора.
|
|
|
Записан
|
|
|
|
Джон
просто
Администратор
Offline
Пол:
|
|
« Ответ #16 : 06-05-2004 07:23 » |
|
А тогда пробовал в консольном - там ни хрена. Слушай, а может когда ты консольную версию компилишь, так там исключения уже отлавливаются? Ну там какие нить диррективы компилятору, или что-нить в этом роде? Я с Борландом не работал. Но try-catch входит в стандарь языка, а посему должно работать везде.
|
|
|
Записан
|
Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома. "Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash "Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman "All science is either physics or stamp collecting." Ernest Rutherford "Wer will, findet Wege, wer nicht will, findet Gründe."
|
|
|
DerSpieler
Гость
|
|
« Ответ #17 : 06-05-2004 08:12 » |
|
Да ну ладно пускай программа будет с глюком Просто не хотелось бы, чтоб он вылез на презентации.
|
|
|
Записан
|
|
|
|
Доброжелатель
Гость
|
|
« Ответ #18 : 06-05-2004 10:23 » |
|
В стандарте написано что, как деление на ноль, так и переполнение целого есть неопределённое поведение, т.е. в данных случаях вызова исключений ожидать не приходится. :? Таким образом, придётся каждый делитель проверять на равенство нулю. Вот такая нелегкая доля
|
|
|
Записан
|
|
|
|
DerSpieler
Гость
|
|
« Ответ #19 : 06-05-2004 17:44 » |
|
Обидно А ведь иногда обрабатывается
|
|
|
Записан
|
|
|
|
Mayor
Специалист
Offline
|
|
« Ответ #20 : 09-05-2004 04:03 » |
|
Давно я не вспоминал про исключения ...
Ключевая разница (IMHO) между catch и except в том , что как и было сказано ранее catch - c++ , а except - с , поэтому из except можно получит контекст процессора до обработки исключения и как следствие имеется возможность изменить контекст\код\данные и вернуться к выполнению сбойного кода , catch позволяет только обработать исключение - возврат к сбойной инструкции , вроде , не предусмотрен .
Реализация обработки исключений зависит от компилятора , например , в MSVC для всех конструкций try - catch / try - except используется единый кадр стека исключений , как реализовано в borland не знаю , но если для тебя это критично и нет необходимости переноса приложения из Windows на другую OS , можешь в любом компиляторе создать свой кадр стека исключений и до сгенереного компилятором обработчика обрабатывать интересующие тебя исключения .
|
|
|
Записан
|
1n c0de we trust
|
|
|
Serega
Гость
|
|
« Ответ #21 : 09-05-2004 07:42 » |
|
___try, __except и __finally это не С, это MS extension to the C
В С нет поддержки обработки исключений
|
|
|
Записан
|
|
|
|
|