-1

So I was playing around with the concept of inheritance in C++ to get a better understanding of it and I used static_cast to cast adress of a base class object to a derived class pointer.

class A
{
public:
    A() { cout << "A's constructor called " << endl; }
};


class B:public A
{

public:
    B() { cout << "B's constructor called " << endl; }

    void funcinB() { cout << "Hello from B" << endl; }

};

int main()
{
    A a;
    B *b = static_cast<B*>(&a);
    if (b)
    {
        b->funcinB();
    }

}

the program calls B's method, which is something I don't understand as the derived class object was never consructed. following is the output of the program

A's constructor called
Hello from B

Now I know you're not suposed to use static_cast this way, but I'm looking for an explanation as to why the program was able to call B's method.

Thanks!

Abhishek
  • 31
  • 6
  • Strictly there is no explanation, as it is undefined behavior. In practice there is nothing in the function that uses `B`. It could just as well have been a free function or a static member. – Bo Persson Aug 26 '17 at 17:40
  • Downvoter care to explain why the downvote?. I feel it is a valid question and I couldn't find an answer after a reasonable amount of time spent searching for it. – Abhishek Aug 26 '17 at 17:58
  • 2
    Just a guess that the downvoter has seen this many times before and believe you could have found the answer already, like in [Downcasting using the static_cast in C++](https://stackoverflow.com/questions/6322949/downcasting-using-the-static-cast-in-c?noredirect=1&lq=1) – Bo Persson Aug 26 '17 at 18:08
  • That post is helpful but it still doesn't answer what might be the reason behind the program being able to call B's method, as explained in the answers to this questions. – Abhishek Aug 26 '17 at 18:26

2 Answers2

3

Your program has undefined behavior.

Your program works since many, if not all, compilers translate

b->funcinB();

to

funcinB(b);

where the member function is implemented as:

void funcinB(B* const this) { cout << "Hello from B" << endl; }

The behavior would have been different had you tried to access any member variables of B in the function.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

The method itself is just a function somewhere - it always has the same address.

In fact, you can imagine (and, by all calling conventions I know, this is actually the case) that calling object.method(12) actually calls a function called classname_method(classname *this, int parameter). What changes when you call the method on different objects is just the this pointer, not the method!

So, if you convince your compiler that your pointer points to a derived class instance, then it will happily call the method on that.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
  • Does the compiler actually change the method name to "classname_method" (in my case "B_funcinB")? – Abhishek Aug 26 '17 at 18:03
  • 1
    kind of; it's called *name mangling*. Your `void B::funcinB()` becomes, after GCC standard name mangling, a C function symbol called `_ZN1B7funcinBEv` – Marcus Müller Aug 26 '17 at 18:18
  • 1
    but note that this is totally implementation-specific. as a programmer, you **never** deal with these symbols directly, unless you're writing something that is a C++ compiler or needs to be able to parse C++ libraries (you don't.). – Marcus Müller Aug 26 '17 at 18:21