为什么显式类型转换允许向上转换私有继承?

Dbl*_*e47 25 c++

#include<iostream>
using namespace std;

class A {
    public:
    void f(){cout<<"A"<<endl;}
};

class B : private A {
    public:
    void f(){cout<<"B"<<endl;}
};

int main (){
Run Code Online (Sandbox Code Playgroud)

由于B类私下继承A类,因此这种向上转换不应该起作用:

    A* a = new B;
Run Code Online (Sandbox Code Playgroud)

但明确的类型转换允许它.为什么?

    A* a1 = (A*)new B;
    a1->f();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Che*_*Alf 18

演员阵容

A* a1 = (A*)new B;
Run Code Online (Sandbox Code Playgroud)

是一个转换为无法访问的基类.

它只能表示为C样式转换.它相当于什么static_cast,如果会做static_cast可以在这种情况下使用,并且它并不等同于一个reinterpret_cast.特别是结果地址不一定与参数地址相同.

C++11§5.4/ 4:

" 相同的语义限制和行为[对于a static_cast]适用[对于C样式转换],但static_cast在以下情况下执行a时,即使基类不可访问,转换也是有效的:

- 指向派生类类型的对象的指针或派生类类型的左值或右值可以分别显式转换为指针或对明确基类类型的引用;

  • @RichardHodges:转换为无法访问的基类,并且`dynamic_cast`,甚至`static_cast`用于一般情况,不能用`reinterpret_cast`和`const_cast`表示.即你的陈述"如果它不能用reinterpret_cast和const_cast来表达,它根本不是一个有效的演员."是一个无意义的断言.抱歉. (5认同)
  • 如果它不能用reinterpret_cast和const_cast表示,那么根本不是有效的演员表. (2认同)

Tar*_*ama 8

这是C风格演员表的规则所允许的:

(N3337)[expr.cast]/4:由...执行的转换

  • 一个const_cast(5.2.11),
  • 一个static_cast(5.2.9),
  • static_cast后跟const_cast,
  • reinterpret_cast(5.2.10),或
  • 一个reinterpret_cast后跟一个const_cast,

可以使用显式类型转换的强制转换表示法执行.应用相同的语义限制和行为,但在以下情况下执行static_cast时,即使基类不可访问,转换也是有效的:

  • 指向派生类类型的对象的指针或派生类类型的左值或右值可以分别显式转换为指针或对明确基类类型的引用;

  • [...]

如果更改为a static_cast,则无法编译.GCC给出了这个错误:

error: 'A' is an inaccessible base of 'B'
    A* a1 = static_cast<A*>(new B);
Run Code Online (Sandbox Code Playgroud)


Ale*_*ota 5

明确的施法可以让你做任何你想做的事情.例如,您可以这样写:

int *p = (int*)new B; 
Run Code Online (Sandbox Code Playgroud)

并且代码将被编译.明确的演员表示你知道自己在做什么.

  • *明确的演员意味着你知道你在做什么.*=>通常相反.:-) (12认同)