通过强制转换切掉覆盖的方法



我有一个从 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。当然,如果一个接口实际上privatevirtual功能,那么这个接口的用户就无法挽回这个设计错误。

看到提倡可怕黑客(#define private protected(的答案获得赞成票,我建议宁愿依赖添加的非virtual成员函数而不更改对象布局并编辑头文件以添加合适的函数:

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

此更改具有更局部的效果,并且也不便携。但是,它仅仅依赖于对象布局,而不是通过添加非virtual(inline(方法和访问说明符来更改。语言级别等的警告不会受到影响。

没有

一致的方法来调用派生类中的私有函数。

至少在没有friend或成员模板的情况下,您可以专注于自己的私人类型,在遵守法律条文的同时颠覆意图。

  1. 尽管如此,还是有#define private public -hack,它可能适用于您的实现.
    不过,这是未定义的行为,所以不要抱怨它不是在任何地方都有效。可能的故障模式是链接错误,尽管理论上它可以变得任意奇怪。

  2. 更可靠的是添加一个非虚拟受保护的内联转发器,尽管这意味着实际编辑标头。

  3. 此外,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

    关闭所有访问权限检查。此开关主要用于解决访问控制代码中的错误。

相关内容

  • 没有找到相关文章

最新更新