C++ Polymorphism. Why is this working?

115 views Asked by At

Shouldn't this be incorrect ? :

A* apb = (A*)&b; //a pointer to b

I would expect an error, or at least a warning.

Why is this not giving me any warning either in Visual C++ 2013 (v120) or in g++ (gcc 4.8.2) ?

#ifndef A_H
#define A_H

#include <stdio.h>

class A
{
public:
   A(){}
   virtual ~A(){}
   void print(){ printf("printA\n"); }
   virtual void printVirtual(){ printf("printVirtualA\n"); }
};

#endif // A_H

#ifndef B_H
#define B_H

#include "A.hpp"
class B : A
{
public:
   B(){}
   void print(){ printf("printB\n"); }
   virtual void printVirtual(){ printf("printVirtualB\n"); }
};

#endif //B_H

int main()
{
   A a;
   B b;
   A* apb = (A*)&b; //a pointer to b
   B* bpa = (B*)&a; //b pointer to a

   apb->print();         // printA
   apb->printVirtual();  // printVirtualB
   bpa->print();         // printB
   bpa->printVirtual();  // printVirtualA
   return 0;
}

Output:

printA
printVirtualB
printB
printVirtualA

I suspect it is because my classes are align in memory so there is a valid Vtable.

Is this an "implicit" dynamic_cast ?

From what I have learned it should not be correct to do this.

3

There are 3 answers

4
Jules Gagnon-Marchand On BEST ANSWER

this is exactly what vtables are for. non-virtual functions are called matching the type of the container, and virtual functions are called matching the type of the pointed object.

A* apb = (A*) &b;

.... is perfectly fine code, and is a classic example of virtual polymorphism.

0
Ali Kazmi On
A* apb = (A*) &b;

This is perfectly alright. Base pointer pointing to derieved object. This scheme is mostly followed by abstract classes (or interfaces) to anable polymorphism

2
πάντα ῥεῖ On
A* apb = (A*)&b;

Is perfectly OK to initialize a base class pointer from a derived class (supposed b is of type B as you're showing). You don't even need the cast operation

A* apb = &b;

The void print() member functions aren't marked virtual, thus the member functions are called on the actual instance you have at hand.