Каким будет вывод программы - обработка исключений? - PullRequest
0 голосов
/ 29 октября 2019
#include <iostream>

struct GeneralException {
  virtual void print() { std::cout << "G"; }
};

struct SpecialException : public GeneralException {
  void print() override { std::cout << "S"; }
};

void f() { throw SpecialException(); }

int main() {
  try {
    f();
  }
  catch (GeneralException e) {
    e.print();
  }
}

В методе main, когда вызывается функция f (), он вызывает исключение SpecialException. Я был смущен, что бы бросить SpecialException () сделать? Вызовет ли он конструктор struct SpecialException (который не определен).

Ответы [ 3 ]

1 голос
/ 29 октября 2019

Код:

throw SpecialException();

Это значение по умолчанию - создает экземпляр SpecialException и выбрасывает его. Для SpecialException не зарегистрирован зарегистрированный специальный обработчик, но есть один для базового класса, GeneralException, по значению , что означает, что ваш экземпляр SpecialException будет скопирован с помощью copy-ctor-slice вGeneralException, и в результате получается печать .. G

, если вы надеялись / ожидали печати S, вы должны поймать это исключение по ссылке, предпочтительно const, что потребует создания print const в обеих реализациях. Результат будет выглядеть так:

#include <iostream>

struct GeneralException {
    virtual void print() const { std::cout << "G"; }
};

struct SpecialException : public GeneralException {
    void print() const override { std::cout << "S"; }
};

void f() { throw SpecialException(); }

int main() {
    try {
        f();
    }
    catch (GeneralException const& e) {
        e.print();
    }
}

Вывод

S
0 голосов
/ 29 октября 2019

Вывод будет

G

Проще говоря, когда вы пишете throw SpecialException(), он только создает объект SpecialException и передает его объекту GeneralException e вcatch block.

Другими словами, если я соберу все вместе, вы можете предположить, что это именно то, что происходит на самом деле. e.print(); напечатает G - версию print(), определенную в классе GeneralException.

Чтобы воспользоваться преимуществами полиморфизма, обновите код, как уже упоминалось в ответе @WhozCraig.

0 голосов
/ 29 октября 2019

Я думаю, вы не понимаете, как ловить и бросать работу. Позвольте мне показать это с помощью синпета кода.

       while(ch != 'n'){
       try{
        cout<<"Enter some number"'; // Let us suppose we want to  enter some int.
        cin>>num; // think that you enter char here.Ideally it show exit due to your input.But since we have made this statement in try block. It'll try to look for some handler who can handle such errors.
        cout<<"Wanna enter more. Enter y or n -"<<endl;
        cin>>ch;
        if(!cin){ // since you entered char when int was required. stream will corrupt.
            throw runtime_error("Input failed.\n");} // here we are throwing it.We are throwing it to runtime_error. It will search for it and go to that block.
    }
    catch(runtime_error error){ // This will catch it.
        cout<<error.what()
            <<"Try again? Enter y or n.\n";
            char c; //if you enter y it will go back to take input since it's while loop.
            cin>>c;
            if(!cin || c=='n'){
                break;
            }
    }
     }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...