Почему reinterpret_cast работает в частном наследовании - PullRequest
0 голосов
/ 03 июля 2018

Я читал о спецификаторах доступа при применении наследования, и я знаю, что в 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 голосов
/ 03 июля 2018

Нарушается ли частное наследство? Не совсем.

Доступность в C ++ влияет только на то, в каких областях можно использовать идентификатор для ссылки на что-либо действительным образом. Система разработана для защиты от Мерфи, а не от макиавеллиевских уловок, которые вы используете.

reinterpret_cast в основном вы говорите компилятору "забудьте то, что вы знаете, вместо этого верьте моему суждению" . Так оно и есть. Вы утверждаете, что это значение действительно относится к base? Хорошо, по-твоему. Но компилятор не собирается ничего делать, чтобы защитить вас, он предполагает, что вы знаете, что делаете. Это может сломаться довольно легко. Вот пример @ Дани, и вот этот:

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

Как вы думаете, что произойдет, если вы попытаетесь использовать c и вызвать функцию-член, которая использует _a? Что он найдет вместо этого?

0 голосов
/ 03 июля 2018

reinterpret_cast не совпадает с static_cast
Рассмотрим следующий пример:

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

Приведение C к B с использованием static_cast изменит указатель на правильный результат, в то время как reinterpret_cast оставит указатель таким же, что неверно.

...