1

I'm testing a dynamic_cast<> example in Stroustrup C++ 4th Ed Page 642 and it does not compile. I'm using the following picture directly from the book trying to learn how it works. Does anyone know if this is Eratta (its not in his published errata doc) or I have misread something?

Stroustrup Graphic, dashed line represents protected: Page 642 graphic

#include <iostream>
using namespace std;

// H = Ival_box
class H {
};

// G = Ival_slider
class G : public H {
};

// I = BBwindow
class I {
};

// F = BB_slider
class F : public I {
};

// X = BB_ival_slider
class X : public G, protected F {
};


int main(int argc, char *argv[])
{
    // works
    X xx{};
    if (auto p = dynamic_cast<G*>(&xx))
        cout << "X*...G*" << endl;

    // works
    G gg{};
    if (auto p = dynamic_cast<H*>(&gg))
        cout << "G*...H*" << endl;

    // compilation error, 'I' is not polymorphic
    I ii{};
    if (auto p = dynamic_cast<H*>(&ii))
        cout << "I*...H*" << endl;

    return 0;
}

Compilation and results:

clang++ -std=c++11 -pedantic -Wall test164.cc && ./a.out
test164.cc:31:18: error: 'I' is not polymorphic
    if (auto p = dynamic_cast<H*>(&ii))
                 ^                ~~~
1 error generated.

Compilation and results with error commented out:

clang++ -std=c++11 -pedantic -Wall test164.cc && ./a.out
X*...G*
G*...H*
notaorb
  • 1,944
  • 1
  • 8
  • 18
  • None of your classes are polymorphic. You need to the keyword `virtual` somewhere in the class to make it polymorphic. – NathanOliver Jun 29 '20 at 16:24
  • I thought virtual (per last section of book) is if two classes share a common base class as a solution to the diamond? – notaorb Jun 29 '20 at 16:25
  • No, `virtual` is a keyword and only happens if you use it. It's used to solve the diamond problem, but you don't get it automatically if you have a diamond. – NathanOliver Jun 29 '20 at 16:26
  • @NathanOliver: I think you're confusing OP by refering to [virtual inheritance](https://stackoverflow.com/questions/21558/in-c-what-is-a-virtual-base-class), which OP shouldn't care about. See OP's comment on eerorika's answer. – einpoklum Jun 29 '20 at 16:30

1 Answers1

2

The error explains what is wrong. Dynamic cast is only allowed for polymorphic types (except when casting upwards in inheritance hierarchy).

A class is polymorphic only if it has at least one virtual function. I does not have any virtual functions. Therefore it is not polymorphic. You must add a virtual function to I in order for this to work.

Note that even then, dynamic_cast<H*>(&ii) can never be a non-null pointer (i.e. true) because ii is not a base sub object of an object of type H.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • so `class F : virtual public I {` that doesn't work – notaorb Jun 29 '20 at 16:28
  • @notaorb Indeed not. That is not a virtual function. – eerorika Jun 29 '20 at 16:29
  • So I add `class I {virtual void f(void) {}};` and that solves the problem. Still unclear why that fixes this. – notaorb Jun 29 '20 at 16:31
  • @notaorb Added clarification. – eerorika Jun 29 '20 at 16:32
  • Here is fixed example (adding virtual destructor to base classes): https://wandbox.org/permlink/6g4RZ4buf5t6D0us – Marek R Jun 29 '20 at 16:38
  • @MarekR I recommend using `= default` for the virtual destructor. – eerorika Jun 29 '20 at 16:53
  • @eeroika RE: `dynamic_cast(&ii)` can never be a non-null pointer. It makes me wonder if Stroustrup intended the non-null or null in his example. Why would he chose a negative case in the explanation. – notaorb Jun 29 '20 at 16:54
  • @notaorb I don't know if you've quoted the code from the book verbatim, nor how Stroustrup has explained the code in the book, so I cannot answer. – eerorika Jun 29 '20 at 16:58
  • @eerorika "because ii is not a base sub object of an object of type H" did you mean, "because H is not a base sub object of ii"? – notaorb Jun 29 '20 at 17:02
  • @notaorb I didn't mean that, but that would be another case where the cast would work. – eerorika Jun 29 '20 at 17:03
  • @notaorb I checked my 3rd edition of the book, and cannot find example code that would correspond to what you wrote in the question. – eerorika Jun 29 '20 at 17:06
  • @eerorika I used the hierarchy diagram and example on P642 of the 4th Ed to create it. It's not 1-1. Thanks for checking! – notaorb Jun 29 '20 at 17:07