Monday, March 28, 2011

calling base class functions

I have following classes.

class A
{

public:

void fun();

}

class B: public A
{

}

class C: public A
{

}

A * ptr = new C;

Is it ok to do something like below? Will i have some problems if introduce some virtual functions in the baseclass?

((B *)ptr)->fun();

This may look stupid, but i have a function that calls A's function through B and i don't want to change that.

From stackoverflow
  • You can't cast an A* pointing to Class C as a B* because Class C doesn't have any relation with Class B. You'll get undefined behavior which will probably be the wrong function called and stack corruption.

    If you intended for class C to derive from class B then you could. However, you wouldn't need to. If class C doesn't have fun() defined, it will inherit A's. You didn't declare fun() virtual though so you'll get strange behavior if you even implement C::fun() or B::fun(). You almost certainly want fun() to be declared virtual.

    Kevin Loney : Actually you can cast an A* pointing to Class as a B* that's one of the beautiful/hideous things about c++. It's definitely not a good idea though.
    Steve Rowe : You are correct. It's possible, but you'll probably get stack corruption as I noted. Maybe I should have said, "You can't *safely* cast..."
    MSalters : Hairsplitting really. You can write 1/0, but that still doesn't mean you can divide by zero.
  • You don't have to do the casting (B*) ptr->fun(); since the fun() is already in the base class. both objects of class B or C will invoke the same fun() function in your example.

    I'm not sure what happens when u override the fun() function in class B...

    But trying to invoke function from another class (not the base class) is bad OO, in my opinion.

    Kevin Loney : What he has is correct because C is derived from A so the cast to (A*) is unnecessary.
  • I'm guessing here but I suspect the behavior of this might depend on the compiler you use and how it decides to organize the vf pointer table.

    I'm also going to note that I think what you are doing is a bad idea and could lead to all kinds of nightmarish problems (use of things like static_cast and dynamic_cast are generally a good idea). The other thing is because fun() is defined in the base class (and it is not virtual) ptr->fun() will always call A::fun() without having to cast it to B*.

  • You can cast from A * to B *, and it should work if the original pointer was B *.

    A* p = new B;
    B* q = static_cast<B*>(p); // Just work (tm)
    

    But in this case it is a C *, and it is not guaranteed to work, you will end with a dangling pointer, if you are lucky you will get an access violation, if not you man end up silently corrupting your memory.

    A* p = new C;
    B* q = static_cast<B*>(p); // Owned (tm)
    

0 comments:

Post a Comment