我有一个从 A 公开继承的类 B:
class A {
private:
virtual void method();
}
class B : public A {
private:
void method();
}
现在,我需要以某种方式调用B::method()
中的原始A::method()
,而无需调用 A 的复制构造函数。
A 是在我尝试扩展的库中定义的,所以我无法更改此代码(例如使方法受保护(。是否有可能以某种方式在 B::method()
内投射 this
ptr 并切掉被覆盖的method
?
我正在使用调用A::method()
的外部接口。此接口正确调用了我被覆盖的B::method()
,但我似乎无法在其中调用接口B::method()
而不会生成堆栈溢出。
由于private
方法不能称为限定方法,并且重写无法撤消,因此如果没有其他对象,您将无法调用private
方法。强制转换对象不会产生任何影响,因为处理虚拟函数的方式是实际对象的一部分。
过去,我主张将所有virtual
函数(析构函数除外(private
但调用基类版本的需求实际上并不少见。因此,virtual
函数不应该private
,而应该protected
。当然,如果一个接口实际上private
其virtual
功能,那么这个接口的用户就无法挽回这个设计错误。
看到提倡可怕黑客(#define private protected
(的答案获得赞成票,我建议宁愿依赖添加的非virtual
成员函数而不更改对象布局并编辑头文件以添加合适的函数:
class A {
private:
virtual void method();
protected:
void call_method() { this->A::method(); }
};
此更改具有更局部的效果,并且也不便携。但是,它仅仅依赖于对象布局,而不是通过添加非virtual
(inline
(方法和访问说明符来更改。语言级别等的警告不会受到影响。
一致的方法来调用派生类中的私有函数。
至少在没有friend
或成员模板的情况下,您可以专注于自己的私人类型,在遵守法律条文的同时颠覆意图。
尽管如此,还是有
#define private public
-hack,它可能适用于您的实现.
不过,这是未定义的行为,所以不要抱怨它不是在任何地方都有效。可能的故障模式是链接错误,尽管理论上它可以变得任意奇怪。更可靠的是添加一个非虚拟受保护的内联转发器,尽管这意味着实际编辑标头。
此外,gcc 还
-fno-access-control
禁用所有访问检查:https://gcc.gnu.org/onlinedocs/gcc-4.9.2/gcc/C_002b_002b-Dialect-Options.html#C_002b_002b-Dialect-Options关闭所有访问权限检查。此开关主要用于解决访问控制代码中的错误。