为什么reinterpret_cast在私人继承中确实起作用

时间:2018-07-03 10:13:03

标签: c++ casting reinterpret-cast

我在阅读有关应用继承时的访问说明符,我知道在private inheritance中我们无法使用指针/引用将其从派生转换为基类。

但是当我使用reinterpret_cast时,它起作用了。下面是我的测试代码:

class base {
int _a;
public: 
    base(int a): _a(a) {}
    base(): _a(0) {}
};

class derived : private base
{
public:
    derived(int b):base(b) {};  
};

int main() {

    derived b(25); 
    base &a = static_cast<base&>(b);//this line will generate a compile error
    base &c = reinterpret_cast<base&>(b);  //here it works 
}

所以我的问题甚至在进行私有继承,为什么使用retinterpret_cast公开基类?

谢谢!

//EDIT 2

class base {
    int _a; 
public:         
    base(int a): _a(a) {}
    base(): _a(100) {}  
    ~base() { std::cout << "deleting base" << _a << "\n"; }
};

class derived : private base
{
public:
    virtual ~derived() = default;
    derived(int b):base(b) {};
};

int main() {

    derived b(25); 
    base &c = reinterpret_cast<base&>(b); 
}

//OutPut : Deleting 25

2 个答案:

答案 0 :(得分:3)

是否侵犯了私人继承?不是。

C ++中的可访问性仅影响标识符可以在什么范围内以有效方式引用事物。该系统旨在保护您免受Murphy的侵害,而不是像您使用的Machiavellian一样。

reinterpret_cast基本上是您告诉编译器“忘记您所知道的,改为相信我的判断” 。确实如此。您声称这个左值实际上是指base吗?很好,随你便便。但是编译器不会做任何保护您的事情,它假设您知道自己在做什么。它很容易折断。有@Dani的例子,有一个例子:

class derived : private base
{
public:
    virtual ~derived() = default;
    derived(int b):base(b) {};  
};

如果您尝试使用c并调用使用_a的成员函数,您会怎么办?它将找到什么呢?

答案 1 :(得分:1)

reinterpret_caststatic_cast不同
考虑以下示例:

class A { int a; }
class B { int b; }
class C : public A, B { }

使用static_cast将C投射到B会将指针更改为正确的结果,而reinterpret_cast则将指针保持不变,这是不正确的。