3

I read the following from C++ Primer (5th edition, Section 18.1.1): "When we throw an expression, the static, compile-time type of that expression determines the type of the exception object."

By "the type of the exception object", does the author mean the dynamic type or the static type of the exception object?

Here is a related question: Static type of the exception object

yuanlu0210
  • 193
  • 6

1 Answers1

2

I think you are having trouble grasping dynamic and static typing in general. So let's address that, and leave the exceptions on the side line, for a second.

First, when do static and dynamic types come into play? The answer is run-time polymorphism. Now, while you may have heard the expression "polymorphic types" thrown around, you should know there is no such thing. Types are not polymorphic.

But they can be used polymorphically! That distinction is important, and I hope you'll see why soon. Let's look at a simple case study:

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

struct Derived : Base {
  void print() const override { std::cout << "Derived"; }
};

void foo(Base& b) {
  b.print();
}

int main() {
  Derived d;
  foo(d);
}

Inside foo we can use the reference b which is bound to some Base object. What is the type of the expression b? It's Base. Because if we were to create a copy of the referred to object, we'd get a Base. This is what is known as the static type of the object. The type that is written in the declaration, plain and simple. Furthermore, inside main, what is the type of d? It's Derived, for the same reason.

But what happens when you pass d to foo?

The reference b binds to it, which is allowed, of course. It's "real", dynamic type, is Derived. But foo refers to it with a Base&. This is what polymorphic usage is. Even though the function sees one type, it is in fact another. And because of the indirection, it's the "other" type that is operated upon via the virtual function mechanism.

Now let's apply it to your question. Throwing will make a copy of the object. The type of the copied object is determined by the expression it is given. So when you give it a Base&, it's going to create a Base object. The fact it may have really been a reference to a Derived is immaterial. Throwing an exception is not a polymorphic usage.

What could be a polymorphic usage, is the catch clause. If we catch by reference, than the referred to exception object may in fact have a different type than the reference we have.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Thanks (especially for the polymorphic usage illustration)! For some reason, I thought that throwing an exception object this way precludes the possibility of dynamic binding. – yuanlu0210 Oct 22 '17 at 21:09