0
#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();
  }
}

In main method, when f() is being called, it will throw SpecialException. I was confused what would throw SpecialException() do ? Will it call constructor of struct SpecialException (which is not defined).

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Harsh
  • 1
  • 1

3 Answers3

1

The code:

throw SpecialException();

This default-constructs a SpecialException instance and throws it. There is no registered specific handler for SpecialException, but there is one for the base-class, GeneralException, by-value, which means your SpecialException instance will be copy-ctor-sliced into a GeneralException, and the result is a print of..G

if you were hoping/expecting for S to be printed, you have to catch that exception by reference, preferably const, which will require making print const in both implementations. The result would look like this:

#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();
    }
}

Output

S
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
0

I think you are confused about how catch and throw work. Let me show this with a sinppet of code.

       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;
            }
    }
     }
Nikhil Badyal
  • 1,589
  • 1
  • 9
  • 20
0

The output will be

G

In simple terms when you write throw SpecialException() it is only creating an object of SpecialException and passing it to the object of GeneralException e in the catch block.

In other words if I put things together you can assume this is what actually is happening.

//throw statement    
SpecialException s;

//catch statment
GeneralException e = s;
e.print();

From this it is pretty much clear that no polymorphism is taking place and e.print(); will print G which is the version of print() defined in GeneralException class.

To take benefit of polymorphism update your code as already mentioned by @WhozCraig answer.

Syed Ahmed Jamil
  • 1,881
  • 3
  • 18
  • 34