4

I am a newbie in C++. Can anyone tell me why the following source code runs well?

#include <iostream>

using namespace std;

class A{
public:
    A(){ cout << "create a" << endl; }
    void sayGoodbye() { cout << "goodbye" << endl; }
};

class B{
public:
    B() { cout << "create b" << endl; }
    void sayHello() { cout << "hello" << endl; }
};

int main(array<System::String ^> ^args)
{
    A* a = new A();

    ((B*)a)->sayHello();
    a->sayGoodbye();

    return 0;
}

Output:

create a
hello
goodbye

What I wonder is why can the a access B::sayHello just by casting like that? Can it access every public members of any class by that way?

b4hand
  • 9,550
  • 4
  • 44
  • 49

5 Answers5

4

Yes, you can.

But, no, you can't.

When you use a C-style cast like that, you are promising to the computer that you know what you're doing, and that the cast is valid. When it is valid, you're fine. When it's not, it's your fault.

In this case, it's not, and it's your fault.

Now, you can ask why it "runs well", but that's incidental: that's pure chance. Once the program is compiled, it's only going to crash or murder your step-children if you literally access invalid memory. In this particular case, you're not accessing invalid memory.

Doesn't mean you're right, though.

Don't do this.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 1
    The first two sentences are very precise. They describe the C/C++ languages very well. I like that. – dlask Jun 01 '15 at 04:03
2

This is not an answer to your question, however it can give you more knowledge and options when working with pointer casting:

You can see several casting techniques as follows:

static_cast
dynamic_cast
const_cast
reinterpret_cast
C-style cast (type)value
Function-style cast type(value)
Community
  • 1
  • 1
duong_dajgja
  • 4,196
  • 1
  • 38
  • 65
1

In my case, I use dynamic_cast to check this casting problem. And it also helpful in case of down-casting. But have one problem with dynamic_cast in down-casting is that we must have polymorphic class type.

HappyTran
  • 503
  • 6
  • 9
0

Since the functions you defined for classes A and B don't depend on any data stored in those classes, the computer doesn't have to read anything to run the functions and they are able to execute.

In general, though, if the the sayHello method needed to read data stored on the B class, your cast would result in a seg fault or some other serious problem, since that would make the computer read into memory it is being told is allotted to fit an object of type B, which is not the case since the object is of type A.

Joshua Gevirtz
  • 401
  • 3
  • 14
0

sayHello method is not accessing any data member from class B. Also, ((B*)a)->sayHello(); is compiled to something like call-to-mangled-sayHello-member-function-of-B(this) . So, class B member function sayHello will be invoked by passing a pointer to an object of B and that pointer is not being used within the sayHello method. So, it will work in this case.

((B*)0)->sayHello();
((B*)1)->sayHello();
((B*)2)->sayHello();

In fact all the above calls will work. sayHello will receive a this pointer with address 0, 1, 2. As sayHello is not accessing any data member of B, so they will work. If sayHello access any non-static data members, then there will be a big crash. Generally, behavior is undefined. If sayHello is virtual, then there will be real problems. Because, in that case a valid object in memory will be needed to resolve the called function at runtime.

Nipun Talukdar
  • 4,975
  • 6
  • 30
  • 42