Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Исключения, Объясните зачем они 
:(
    Опции темы
Xenon
Дата 11.6.2006, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Немного не понимаю, для чего они, собственно, нужны в некоторых случаях ...
Ну вот у меня метод из классы, для записи файла
Код

void album::write()
{
    ofstream outfile;
    outfile.open("collection.dat",ios::binary | ios::app);
    cout << "Writing to file ...\n";
    if (!outfile)
    {
        cout << "Error";
    }
    for (int j=0;j<n;j++)
    {
        outfile.write((char*)(albums[j]),sizeof(album));
    }
    if (outfile.good()==1)
    {
        cout << "Completed";
    }
    is_changed=false;
}


Если ошибку обработать при помощи исключений, то получится:
Код

void album::write()
{
    ofstream outfile;
    outfile.open("collection.dat",ios::binary | ios::app);
    cout << "Writing to file ...\n";
    if (!outfile)
    {
        throw Error();
    }
    for (int j=0;j<n;j++)
    {
        outfile.write((char*)(albums[j]),sizeof(album));
    }
    if (outfile.good()==1)
    {
        cout << "Completed";
    }
    is_changed=false;
}

И какое тогда премущество ? То, что вся обработка ошибка запихнута в catch а не раскадинана по методам классов и только?
Не понимаю зачем они нужны ... Приведите, если не сложно, примеры, а то я чего-то запутался smile 


--------------------
user posted image  
PM MAIL   Вверх
Void
Дата 11.6.2006, 20:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 40
Всего: 173



Исключения нужны, чтобы обрабатывать ошибку не на том уровне логики, где она возникает, а выше, где приложению ясно, что с ней делать. 


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
MAKCim
Дата 11.6.2006, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



исключения - унифицированный способ обработки ошибок
при использовании исключений получаем все претмущества классов (в частности полиморфизм) 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Xenon
Дата 11.6.2006, 21:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Хм ... а пример? Приведите пример, где это удобнее, чтобы очевидно почувствовать разницу.
PS. По правилам хорошего кодинга для каждого класса нужно создавать один класс, например, Error, для схватки ошибок, или же лучше ошибки разбивать на разные группы? 


--------------------
user posted image  
PM MAIL   Вверх
Dray
Дата 11.6.2006, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



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


--------------------
忍者

user posted image
PM MAIL   Вверх
MAKCim
Дата 12.6.2006, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Хм ... а пример? Приведите пример, где это удобнее, чтобы очевидно почувствовать разницу.

имхо, в любом случае удобнее 


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Xenon
Дата 12.6.2006, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



MAKCim, Ну вот в том варианте, что я кинул, имхо, нет smile  

Это сообщение отредактировал(а) XenonSk - 12.6.2006, 21:13


--------------------
user posted image  
PM MAIL   Вверх
Daevaorn
Дата 12.6.2006, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(XenonSk @  12.6.2006,  22:13 Найти цитируемый пост)
Ну вот в том варианте, что я кинул, имхо, нет 

Зато как хорошо вызывающему коду отлавливать ошибку записи, а? Плюс безопасность исключений требует не просто применения throw/catch, но и изменение дизайна класса/функции. При грамотном использовании удобство чувствуется очень сильно - упрощает жизнь.
 
PM MAIL WWW   Вверх
MAKCim
Дата 12.6.2006, 21:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Цитата

Ну вот в том варианте, что я кинул, имхо, нет 

ну да,
Код

if (!outfile)
    {
        cout << "Error";
    }

получается что если !outfile то выводится сообщение об ошибке и программа выполняется дальше?
outfile не открылся а туда что-то записывается?
здесь как раз вариант с исключениями правильнее  

Это сообщение отредактировал(а) MAKCim - 12.6.2006, 21:28


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Dray
Дата 12.6.2006, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



Все опять же зависит от случаяя. Исключения все равно не стоит использовать везде подряд, например если нужно обрабатывать ввод пользователя по каким-то ограничениям, то исключения вряд ли будут логичным решением. А вот например низкоуровневые вещи, о которых пользователь знать не должен, сообщения об ошибках которые адресованы разработчику, лучше генерировать исключениями.
Еще пример можно привести - это написание различных библиотек, где предпологается, что ими будут пользоваться разработчики которые не знают об их устройстве. Чтобы руководить их действиями и указывать на то что они не правильно используют тот или иной класс, удобней использовать исключения.
Это ВсЁ моЁ ИМХО! 


--------------------
忍者

user posted image
PM MAIL   Вверх
Xenon
Дата 12.6.2006, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Dray, Ну, то есть, ты предлагаешь юзать только, фактически, badalloc?

MAKCim, Ну тут же я открываю файл и знаю, если произошла ошибка, то, скорее всего, это связано с некотрыванием файла smile Если я в него пишу данные, то, скорее всего,  с тем, что они туда не пишутся. Не понимаю в чем выгода, хоть убей ... И что значит правильнее?
Ну вот вся прога ... Я только в некоторых местах воткнул исключения и не понял, чего они мне тут дают. Говорю, писали, что преимущество в том, что ты не знаешь, какая ошибка, но ведь это можно на месте проверить в том же методе?
Код

//albums.h
#include <iostream>
#include <iomanip>
#include <string>    
#include <fstream>

const int MAX=30;
using namespace std;
///////////////////////////////////////////////////////
class album    
{    
private:    
    int year;    
    string name;    
    string artist;
    string genre;    
    int cd_num;    
    static album* albums[];
    static int n;
public:    
    static bool is_changed;
    class Error {};
    void enter_data();
    void get_data();
    static void write();//
    static void edit_data();//Коррекция альбома
    static void add();//Добавление альбома
    static void display_all();//Отображение всех альбомов
    static void read(); //Чтение из файла
};

Код

//albums.cpp
#include "albums.h"

///////////////////////////////////////////////////////
///Статические переменные
int album::n;
album* album::albums[MAX];
bool album::is_changed=false;
///////////////////////////////////////////////////////
///Отображение всех альбомов
void album::display_all()
{
    if (n==0)
    {
        cout << "\nThere are no albums\n";
    }
    else
    {
        for (int j=0;j<n;j++)
        {
            albums[j]->get_data();
        }
    }
}
///////////////////////////////////////////////////////
///Добавление альбома
void album::add()
{
    is_changed=true;
    albums[n]=new album;
    albums[n++]->enter_data();
}
///////////////////////////////////////////////////////
///Ввод данных о компакте с клавиатуры
void album::enter_data()    
{    
    cout << "Enter Artist: ";
    cin >> artist;
    cout << "Enter Album: ";    
    cin >> name;    
    cout << "Enter Album`s year ";    
    cin >> year;    
    cout << "Enter Genre: ";    
    cin >> genre;    
}    
/////////////////////////////////////////////////////
///Редактирование альбома
void album::edit_data()    
{
    int i;
    cout << "Enter cd number: ";
    cin >> i;
    albums[i]->enter_data();
}
/////////////////////////////////////////////////////
///Вывод данных об альбоме
void album::get_data()    
{    
    cout << artist << " - " << name << endl;
    cout << "Genre: " << genre << endl;    
    cout << "Year: " << year << endl;    
    cout << "Cd num: " << cd_num << endl;    
}
///////////////////////////////////////////////////////
///Запись в файл данных из ПО
void album::write()
{
    ofstream outfile;
    outfile.open("collection.dat",ios::binary | ios::app);
    cout << "Writing to file ...\n";
    if (!outfile)
    {
        throw Error();
    }
    for (int j=0;j<n;j++)
    {
        outfile.write((char*)(albums[j]),sizeof(album));
    }
    if (outfile.good()==1)
    {
        cout << "Completed";
    }
    is_changed=false;
}
///////////////////////////////////////////////////////
///Чтение данных из файла
void album::read()
{
    cout << "Reading file ... ";
    ifstream inf;
    inf.open("collection.dat",ios::binary);
    if (!inf)
    {
        throw Error();
    }
    else
    {
        n=0;
        while (!inf.eof())
        {
            albums[n]=new album;
            inf.read((char*)(albums[n]),sizeof(album));
            if (inf.eof())
            {
                cout << "Completed";
                break;
            }
            n++;    
        }
    }
}
///////////////////////////////////////////////////////

Код

//main.cpp
#include "albums.h"
#include <conio.h>


int main(int argc, char* argv[])
{    
    int choice;
    do
    {
        try
        {
            cout << "\nWhat to Do? \n1)Display all albums; \n2)Display album; \n3)Add album; \n4)Edit data \n5)Read from file \n6)Save to file \n7)Exit: ";
            cin >> choice;
            switch (choice)
            {
            case 1: album::display_all();
                break;
            case 2: cout << "Enter albums number: "; 
                break;
            case 3: album::add();
                break;
            case 4:album::edit_data();
                break;
            case 5: album::read();
                break;
            case 6: album::write();
                break;
            case 7: break;
            default:cout << "Incorrect choice. Try again";
                break;
            }
        }
        catch (album::Error)
        {
            cout << "Error" << endl;
        }
    }while(choice!=7);
    if (album::is_changed==true)
    {
        do
        {
            char choice;
            cout << "Yo have made changes to file. Do you want to save them? y/n ";
            cin >> choice;
            if (choice=='y' || choice=='Y')
            {
                album::write();
                return false;
            }
            if (choice=='n' || choice=='N')
            {
                return false;
            }
        }while(true);
    }
    _getch();    
    return 0;    
}
  

Это сообщение отредактировал(а) XenonSk - 12.6.2006, 21:49


--------------------
user posted image  
PM MAIL   Вверх
Fazil6
Дата 12.6.2006, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: 35
Всего: 60



Цитата

 Говорю, писали, что преимущество в том, что ты не знаешь, какая ошибка, но ведь это можно на месте проверить в том же методе?

весь фокус в том, что проверить ты можешь, а обработать не всегда. Мало-ли какие у тебя были действия до того как возникла ошибка, т.е как уже говорили исключения нужны для того чтобы ты мог обрабатывать какие-то ситуации не там, где они возникают, а там где тебе удобнее их обрабатывать.

 
PM MAIL   Вверх
Xenon
Дата 12.6.2006, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Fazil6, То есть фишка, как я и писал, только в том, что обработка ошибок организуется - пихается куда хочется. 


--------------------
user posted image  
PM MAIL   Вверх
Dray
Дата 12.6.2006, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Материалист
**


Профиль
Группа: Участник
Сообщений: 652
Регистрация: 7.10.2003
Где: г. Всеволожск

Репутация: 2
Всего: 6



Страуструп сказал надо использовать исключения и всё! Дальше вопрос можно закрывать...  smile  smile  smile 

...Вряд ли найдется человек, который впервые узнав про указатели сразу понял зачем они. Я вот, например, пока не изучил динамические структуры данных так и не понимал зачем эти указатели. А сейчас уже понимаю, что они и не только для связных списков и прочего нужны. С исключениями тоже самое. Их приимущество скорее всего почувствуется позже, в какой-нибудь конкретной ситуации. 


--------------------
忍者

user posted image
PM MAIL   Вверх
Xenon
Дата 12.6.2006, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1529
Регистрация: 12.4.2006

Репутация: 11
Всего: 50



Dray, Не знаю, я не так и долго изучаю C++, да и вообще, как прошел тему про указатели сразу понял что к чему и зачем они нужны, видать книга хорошая. Но искоючения там вскольз описаны, поэтому я жутко торможу, но вроде исходя из постов других я понял, что мои предположении оказались правильными smile 


--------------------
user posted image  
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0928 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.