16
votes

I don't understand why pointers aren't polymorphic types, since we can use base class pointers, which are pointing to derived classes, to call derived class' virtual function. This suggests at runtime, the system can determine if a pointer is polymorphic, doesn't it?

(This is a follow-up question from typeid for polymorphic types)

2
Base class pointers do not point to derived classes. They are pointing to base classes. This pretty much voids the rest of your conclusions.user405725
@VladLazarenko Pointers do not point to classes at all. They point to objects, and those can be of base class, or derived class type. I think that's what the OP means (although, indeed, the wording isn't optimal).jogojapan
What would be different if pointers were considered polymorphic types? Would you be able to do something you cannot do now?n. 1.8e9-where's-my-share m.
@jogojapan: OK, instance of the class, or object, it doesn't matter. Pointer to base never points to derived. Never.user405725
@VladLazarenko What I mean is a situation like this: struct A {}; struct B : A {}; int main() { A* ap = new B; } Here, ap is declared as pointer to base class, but it actually points to an object of the derived class.jogojapan

2 Answers

12
votes

In fact, the Standard (C++11) uses the term polymorphic class type, rather than polymorphic type when it describes the behaviour of typeid:

Firstly, here it describes what happens when typeid is applied to an lvalue of class type (i.e. the case when it does what you expect):

(§5.2.8/2) When typeid is applied to a glvalue expression whose type is a polymorphic class type (10.3), the result refers to a std::type_info object representing the type of the most derived object (1.8) (that is, the dynamic type) to which the glvalue refers. [...]

But when you apply it to a pointer (i.e. not to an lvalue of class type), the rule below applies:

(§5.2.8/3) When typeid is applied to an expression other than a glvalue of a polymorphic class type, the result refers to a std::type_info object representing the static type of the expression. [...]

It says you get the static (not the dynamic) type, i.e. you get the declared type of the pointer, not the type of object it is actually pointing to.

So, yes, pointers have polymorphic characteristics as you describe, but not when it comes to the result of typeid.

(In fact, all of their polymorphic characteristics (including, in particular, polymorphic member function calls) only manifest themselves when some sort of explicit dereferencing, either using * or using ->, is involved. So you should really say that the pointers themselves aren't polymorphic; only the objects you get when you dereference them are.)

7
votes

Your question suffers from incorrect usage of terminology. C++ language makes a very clear distinction between pointers themselves and objects these pointers point to. Pointer types are not polymorphic. There's nothing polymorphic about the pointer itself. What can really be polymorphic is the type the pointer points to. When a pointer points to a polymorphic type, we often [informally] call it polymorphic pointer (just as a shorthand for "a pointer that points to a polymorphic type"). But when it comes to things like typeid, they see things very formally. For typeid pointer types are never polymorphic.

And the compiler does not determine whether the pointer is polymorphic or not at run-time. This simple distinction is always immediately known at compile-time. Again, a pointer is referred to as polymorphic if it is declared as a pointer to polymorphic type. Polymorphic type is a class type that contains virtual functions (directly or indirectly). Obviously, the property of being polymorphic is a purely compile-time property of a type.

The only thing that is determined at run-time in such cases case is which specific type the pointed object has at the given moment.