C ++ исключения в основном - PullRequest
       1

C ++ исключения в основном

1 голос
/ 30 сентября 2011

Мой класс Person имеет разные файлы в качестве атрибутов.

class Person {
private:
    fstream history;
    fstream familyTree;
public:
    Person() { 
        history.open("history.dat"); 
        familyTree.open("tree.dat");
    }
}

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

Если история не открылась, верните 1, если familyTree не открылась, верните 2.

1) Является ли использование исключений единственным решением для этого?

2) Где запускаются исключения?

3) Это неправильно, если я перехватываю исключения в main?

Ответы [ 4 ]

2 голосов
/ 30 сентября 2011

Вы можете генерировать исключения в своем конструкторе и перехватывать их в main. Или вы можете перехватить исключения в своем конструкторе и исправить их так, чтобы класс мог быть правильно инициализирован, что бы ни случилось.

Чтобы сделать ваш класс более тестируемым, конструктор должен выполнять как можно меньше работы. У меня было бы два метода:

bool readHistory (std::string fileName)
bool readFamillyTree (std::string fileName)

вместо того, чтобы пытаться сделать это в конструкторе. Они вернули бы истину, если бы файл мог быть прочитан и был в здравом уме. Вы можете иметь перегруженный конструктор, который вызывает эти методы. Как было указано в комментариях, конструктор должен возвращать пригодный для использования объект. Я предполагаю, что эти файлы не являются необходимыми для функционирования объекта. Это может быть ошибочным.

1 голос
/ 30 сентября 2011

1) Является ли использование исключений единственным решением для этого?

Конечно, нет, существует множество конструкций, предшествующих функциональности исключений, использующих коды возврата, двойная инициализация,и такие техники.Тем не менее, если построение Person требует открытия обоих файлов, и вы не можете этого сделать, то выбрасывание исключения является предпочтительным способом сообщить об этом.Подумайте, что значит для вашего дизайна быть Person и создать конструкцию по умолчанию.

2) Это неправильно, если я перехватываю исключения в main?

Нет, нет.Просто и понятно.

1 голос
/ 30 сентября 2011

1) Является ли использование исключений единственным решением для этого?

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

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

Если main () является ближайшим стеком(это хорошо написано?) туда, где запускаются исключения,

2) Это неправильно, если я ловлю исключения в main?

Совершенно ничего плохого в перехвате исключений в main.На самом деле, лучше всего ловить исключения на самом внешнем уровне, которые могут что-либо сделать с ошибкой;часто это означает, что нужно показать ошибку и закрыть программу, а main - идеальное место.

1 голос
/ 30 сентября 2011

Здесь нет необходимости в исключениях.

bool Person::IsHistoryValid() const
{
    return history;
}

bool Person::IsFamilyTreeValid() const
{
    return familyTree;
}

int main()
{
    Person person;
    if (!person.IsHistoryValid())
        return 1;
    if (!person.IsFamilyTreeValid())
        return 2;
    // do some work
    return 0;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...