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.
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.
There is no conforming way to call the private function in the derived class.
At least if there is no friend
or member-template you can specialize with your own private type to subvert the intent while obeying the letter of the law.
Still, there is the #define private public
-hack, which might work on your implementation.
It's Undefined Behavior though, so don't complain that it does not work everywhere. Probable failure-mode is linking-error, though it can in theory get arbitrarily bizarre.
Far more reliable would be adding a non-virtual protected inline-forwarder, though that means actually editing the header.
Also, gcc has -fno-access-control
to disable all access-checking: https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/C_002b_002b-Dialect-Options.html#C_002b_002b-Dialect-Options
Turn off all access checking. This switch is mainly useful for working around bugs in the access control code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With