dynamic_cast сомнение в C++/Stroustrup: преобразование в защищенный базовый класс

Я знаю, что следующий код дает ошибку компиляции:

class A{ public : virtual void name(){cout<<typeid(this).name()<<endl;}; };
class B:protected A{public : virtual void name(){cout<<typeid(this).name()<<endl;};};
void foo(B* b)
{
    A * a = dynamic_cast<A*>(b); //Error : 'A' is an inaccessible base of 'B'    
    return;
}

Но тогда почему в книге C++ Stroustrup (15.4.1) он пишет

class BB_ival_slider:public Ival_slider,protected BBslider{ //...
};
void f(BB_ival_slider*p)
{  
// ok 
BBslider* pbb2 = dynamic_cast<BBslider*>(p);    // ok: pbb2 becomes 0
}

Разве строка не должна быть ошибкой компиляции? Так что либо мой gcc неверно помечает его как ошибку компиляции, либо немыслимую, неуклюжую опечатку, или, скорее всего, я что-то пропустил...

3 ответа

Решение

Фактическая цитата из 15.4.1:

class BB_ival_slider : public Ival_slider, protected BBslider {
    // ...
};

void f(BB_ival_slider* p)
{
    Ival_slider* pi1 = p; // ok
    Ival_slider* pi2 = dynamic_cast<Ival_slider*>(p); // ok
    BBslider* pbb1 = p; // error: BBslider is a protected base
    BBslider* pbb2 = dynamic_cast<BBslider*>(p); // ok: pbb2 becomes 0
}

Это неинтересный случай. Тем не менее, отрадно знать, что dynamic_cast не допускает случайного нарушения защиты частных и охраняемых базовых классов.

Таким образом, казалось бы, что текст, описывающий код, является правильным, но по неправильным причинам - dynamic_cast не допускает случайного нарушения защиты частных и защищенных базовых классов, но только потому, что его использование будет некорректным и приведет к ошибке компилятора, а не потому, что его использование приведет к нулевому указателю. И, конечно же, код, который описывает текст, определенно верен.

Ошибки случаются - возможно, это будет исправлено в 4-м издании книги.: -]

(Также обратите внимание, что если BB_ival_slider объявляет f быть friend тогда код будет вести себя так, как описано в книге. Возможно это friend Декларация подразумевалась ранее в этой главе, но сейчас у меня нет времени внимательно ее перечитывать, чтобы проверить, так или иначе.)

Я думаю, что если я не нахожу никаких конструктивных доказательств, то я мог бы просто сказать,

"Страуструп был неправ" (звучит страшно:()

Я не думаю, что компиляторам позволено добровольно распространять внутренности класса (согласно определенному стандарту). Если они не пропущены через нож. (операция злой указатель, который есть)

Возможно, он проверял этот код, а может и нет. (Многие авторы помещают непроверенный код в свои книги.) Если он проверял его, имейте в виду, что не все компиляторы созданы равными. G ++ терпит неудачу с error: 'BBslider' is an inaccessible base of 'BB_ival_slider', лязг терпит неудачу с error: cannot cast 'BB_ival_slider' to its protected base class 'BBslider', Другие компиляторы: кто знает? У каждого известного мне компилятора есть проблемы с соответствием стандарту.

Другие вопросы по тегам