2012-04-15 2 views
0

Я читаю главу 16, чтобы начать мои назначения для моего класса C++. Этот раздел посвящен обработке исключений. Я понимаю концепцию конструкции try/catch, однако один из примеров в книге немного сбивает меня с толку. Я надеюсь на некоторое объяснение, как это работает. Пример кода ниже:Выбрасывание объекта класса, определенного в классе

// Includes, header guards, and namespace std... 
class IntRange 
{ 
private: 
    int intput; 
    int lower; 
    int upper; 

public: 
    // Exception class 
    class OutOfRange { }; // This is exactly how it appears in the text. 

    IntRange(int low, int high) { lower = low; upper = high; } 
    int GetInput() 
    { 
    cin >> input; 
    if (input < lower || input > upper) 
     throw OutOfRange(); // <-- This is my question in particular. What is this? 
    return input; 
    } 
}; 

// End header guard. 

// Program entry point. 

int main() 
{ 
    IntRange range(5, 10) 
    int userValue; 

    cout << "Enter a value in the range 5 - 10: "; 
    try 
    { 
    userValue = range.getInput(); 
    cout << "You entered " << userValue << endl; 
    } 
    catch (IntRange::OutOfRange) // <-- Again, what is this delcaration and how can 
           // this data type be defined when IntRange does not 
           // have a default constructor? 
    { 
    cout << "That value is out of range.\n"; 
    } 

    return 0; 
} 

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

Если вы заметили какие-либо ошибки, это скорее всего опечатка, но наиболее важные точки были проверены дважды.

+2

Глава 16 of_what_? –

+0

Начало работы с C++ Ранние объекты - 7-е издание –

ответ

1
throw OutOfRange(); // <-- This is my question in particular. What is this? 

Это по умолчанию создает объект OutOfRange затем бросает его.
Даже если вы не определяете методы в классе, компилятор автоматически сгенерирует пару для вас, один из них является конструктором по умолчанию. Таким образом, даже если вы не укажете конструктор, там будет один (сделайте google в правиле 3/5 для объяснения того, какие методы сгенерированы компилятором).

catch (IntRange::OutOfRange) // <-- Again, what is this delcaration and how can 
          // this data type be defined when IntRange does not 
          // have a default constructor? 

Здесь мы перехватываем объект типа IntRange::OutOfRange.Примечание: we are не ловить объект IntRange. Мы ловим класс OutOfRange, который определяется внутри класса IntRange (кроме того, где он определен, нет других отношений).

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

Также отметим, что лучше перехватывать исключения по константной ссылке:

catch (IntRange::OutOfRange const& e) 

позволяет избежать проблем, связанных с нарезка объектов, которые являются частью исключения иерархии.

+0

ОК, я вижу. Мне казалось, что объект OutOfRange не может быть создан без предварительного экземпляра объекта IntRange. Поэтому, если я понимаю вас, было бы совершенно законно delecare как объект: IntRange :: OutOfRange oor; И если бы у него были члены, я мог бы взаимодействовать с ними, не создав ни одного объекта IntRange? –

+0

@ fhaddad78: Исправлено. Явного отношения между объектом этих типов не существует. OutOfRange является полным типом в своем собственном праве и не имеет никаких неявных ссылок тоже IntRange –

2
throw OutOfRange(); 

Это создает новый экземпляр класса OutOfRange и throw все. Помните, что вы также можете создать экземпляр, как это:

my_method(MyClass()); 

вместо:

MyClass obj; 
my_method(obj); 

Сейчас:

catch (IntRange::OutOfRange) 

OutOfRange является внутренний или вложенный класс из IntRange. См. here

+1

Я просто прочитал этот пример на сайте IBM. Благодаря! Наша книга представляет новые идеи и не дает никаких объяснений. (= –

+0

см. [Здесь] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) для некоторых лучших книг. – ApprenticeHacker

0

Они создают собственное исключение (как класс) под названием OutOfRange и бросают его.

Таким образом, вы можете определенно поймать OutOfRange исключение, таким образом:

try 
{ 
    //do something 
} 
catch (OutOfRange o) 
{ 
    //you know the input was out of range 
} 
catch (Exception e) 
{ 
    //something else went wrong 
} 
0

ваш OutOfRange класс принадлежитIntRange на класс в целом - она ​​не принадлежит какому-либо конкретному объекту, который класс.

Для того, чтобы использовать OutOfRange нет никакого требования даже IntRange на самом деле можно было использовать в качестве конкретного класса, так как IntRange::OutOfRange просто указывает полностью квалифицированное имя типа, а не объект.

в C++ имена типов важны только во время компиляции; информация типа данных (наряду с именами переменных и всеми видами других вещей, подобных этому в вашем коде), как правило, полностью исключена компилятором - типы данных существуют только для того, чтобы помочь вам написать код и выполнить отладку.

+0

Спасибо. Ваши объяснения, а также пара других объяснил, что происходит очень четко. –