Search code examples
c++castingvirtualradixderived-class

Slice off overridden method by casting


I have a class B that inherits publicly from A:

class A {
    private:
    virtual void method();
}

class B : public A {
    private:
    void method();
}

Now, I need to somehow call the original A::method() within B::method(), without invoking the copy constructor for A.
A is defined in a library I'm trying to extend, so I can't change this code (make method protected for example). Is it possible to somehow cast the this ptr within B::method() and slice off the overridden method?

I'm using an external interface that calls A::method(). This interface correctly calls my overridden B::method(), but I can't seem to make the interface call within B::method() not generate a stack overflow.


Solution

  • Since private method can't be called qualified and the override can't be undo you won't be able to call the private method without another object. Casting the object won't have any effect because the way virtual functions are handled is part of the actual object.

    In the past I had advocated making all virtual functions (other than the destructor) private but the need to call the base class version is actually not that uncommon. Thus, virtual functions should not be private but rather protected. Of course, if an interface actually makes its virtual functions private that design mistake can't be undone by the user of this interface.

    Seeing that answers advocating horrible hacks (#define private protected) get upvotes, I'd recommend to rather rely on non-virtual member functions being added not changing the object layout and edit the header file to add a suitable function:

    class A {
    private:
            virtual void method();
    protected:
        void call_method() { this->A::method(); }
    };
    

    This change has a much more local effect and is also just not portable. However, it merely relies on the object layout not being changed by adding a non-virtual (inline) method and an access specifier. No warnings at the language level or so would be affected.