C++ 我可以使用C风格的强制转换将派生类强制转换为私有基类吗?

C++ 我可以使用C风格的强制转换将派生类强制转换为私有基类吗?,c++,casting,upcasting,private-inheritance,C++,Casting,Upcasting,Private Inheritance,我能做这个吗 class A { ... }; class B : private A { const A &foo() const { return *((const A *)this); } }; 我可以将从基类私有继承的子类转换为其基类的公共版本吗?我可以在没有虚拟方法的情况下执行此操作吗 我想是的,但我想确保它是安全的/便携的。是的,你可以:§5.4/7标准: 。。。以下是静态转换和重新解释转换操作 (可选地,后面跟着const_cas

我能做这个吗

class A { ... };

class B : private A
{
    const A &foo() const
    {
        return *((const A *)this);
    }
};
我可以将从基类私有继承的子类转换为其基类的公共版本吗?我可以在没有虚拟方法的情况下执行此操作吗


我想是的,但我想确保它是安全的/便携的。

是的,你可以:§5.4/7标准:

。。。以下是静态转换和重新解释转换操作 (可选地,后面跟着const_cast操作)可以使用 显式类型转换的强制转换表示法,即使基类 类型不可访问:

指向派生类类型的对象或派生类类型的左值的指针 类类型可以显式转换为指向 明确的基类类型


但是尽量不要这样做,因为这违背了私有继承的目的。

根据你的问题标题,答案取决于你。但是对于你的源代码来说,答案是肯定的

有两个因素会影响ANSARE:


  • 如果您使用C样式转换,它将是肯定的,因为如果没有可用的转换,转换将调用re interpert cast。您可以将任何类型的指针强制转换为目标类型的指针。但是如果有MI,对于大多数C++语言实现的结果可能不正确。
  • 如果在memeber函数中执行强制转换(不使用C样式强制转换),Answare将是yes,因为基类在成员函数中是可访问的。如果表达式位于基类不可访问的位置,则会出现编译错误

  • <> C++标准

    中的标准会话有更多的细节
    A prvalue of type “pointer to cv D”, where D is a class type, can be converted to a prvalue of type “pointer to cv B”, where B is a base class (Clause 10) of D. 
    If B is an inaccessible (Clause 11) or ambiguous (10.2) base class of D, a program that necessitates this conversion is ill-formed. 
    The result of the conversion is a pointer to the base class subobject of the derived class object. The null pointer value is converted to the null pointer value of the destination type.
    

    编辑2:使Answare更详细。

    是的,这是明确允许的。Alexandrescu在其基于策略的设计方法中广泛使用了这一点:

    template <typename Policy>
    class foo : Policy
    {
        public:
            void do_something()
            {
                Policy & p = *this;
                p.do_something();
            }
    };
    
    模板
    类别foo:政策
    {
    公众:
    空做某事
    {
    政策&p=*这;
    p、 做某事;
    }
    };
    

    因此,尽管用例可能有限,但仍有一些存在。

    我不确定这是可能的,尽管这会有点违背私有继承的目的……我认为遵循“私有”继承的含义做这件事不是一件好事。这种继承意味着“按实现”,而公共继承是一种“is-a”关系。为什么我想要这种可怕的攻击:关键是从存储配置的键/值字典继承,通常将该字典隐藏在友好的方法后面,以获取/设置各种配置项,但是这样一来,你就可以快速地返回字典了。返回一份副本是可以的,但我想知道是否可以返回常量“this”。显然没有必要,但从代码整洁和惯用代码的角度来看,这并非毫无意义。这是合法的,您不需要C风格的强制转换。事实上,C风格的cast可以在外部用于打破
    private
    关系:
    B;A&ar=*(A*)和b
    即使在
    B
    类之外也会很乐意编译(即C样式转换忽略了访问说明符),为什么要这样做我见过类似的东西被用来将接口与实现分离。在您的类型提供X的接口上,通过在特定API中注册来实现,该API要求您扩展类型
    T
    。从<代码> t>代码>继承不是你的接口,是对特定实现的要求,如果你改变了提供者,那么继承可以在不影响用户代码的情况下被删除。已经做了将近十年的C++,我仍然发现了这种语言的角落。我不确定这是一个关于语言的好评论还是一个坏评论。可能是个坏主意。但是,嘿,为什么现在就停下来呢事实上,它有许多棘手的地方:裸指针、new与new[]、悬空引用、非虚拟析构函数、std::auto_ptr(谢天谢地,它已被弃用)等等。我甚至想把模板添加到列表中,但这可能会招致反对票/普遍嘲笑!但是模板太有趣了!事实上,它们是我最喜欢的语言部分,尽管它们肯定属于瑞士陆军火箭筒类别,而且不会被过度使用。你怎么能把“模板”和“过度使用”这两个词放在同一句话中呢?哦,等等,你没有。但它们仍然靠得太近。建议编辑答案,明确说明这是一个类似于
    静态转换的操作,而不是
    重新解释转换
    您引用的段落是关于隐式类型转换的。它指出,如果基类不可访问,则不能转换指向它的派生类指针。在派生类内部,基类是可访问的,因此这不适用。此外,对于C样式转换还有一个特殊规则,请参见。如果您使用C样式转换,它将是肯定的,因为如果没有转换可用,转换将调用re interpert cast。不,在这种情况下,C样式转换将通过引用的特殊规则Bathsheba执行类似于
    静态\u cast
    (即忽略基类不可访问)。顺便说一句,您应该使用
    或quote按钮插入引号,而不是四个空格或代码按钮。但这不是c样式转换,是吗?它只是从类内部对私有基的隐式转换。我缺少什么吗?隐式转换比c样式转换更受限制。您答案中的代码示例没有任何c样式casts,也不是基类
    策略
    不可访问的任何代码。因此它似乎与OP询问的任何内容都不相关。