【问题标题】:upcast to a protected base using dynamic_cast使用 dynamic_cast 向上转换到受保护的基础
【发布时间】:2015-04-04 15:43:07
【问题描述】:

The c++ programming language这本书有这个代码:

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 nullptr
}

我尝试使用以下代码来证明这种行为以便更好地理解:

#include <iostream>

class Ival_slider {
public:
    Ival_slider() {
        std::cout << "Ival_slider called" << '\n';
    }
};

class BBslider {
public:
    BBslider() {
        std::cout << "BBslider called" << '\n';
    }
};

class BB_ival_slider : public Ival_slider, protected BBslider {
public:
    BB_ival_slider() {
        std::cout << "BB_ival_slider called" << '\n';
    }
};


int main() {
    BB_ival_slider* p = new BB_ival_slider{};
    Ival_slider* p1 = p;
    Ival_slider* p2 = dynamic_cast<Ival_slider*>(p);
    BBslider* pbb2 = dynamic_cast<BBslider*>(p);
    if (pbb2) {
        std::cout << "true" << '\n';
    }
}

然而,

BBslider* pbb2 = dynamic_cast<BBslider*>(p);

似乎没有按预期工作。

g++ -std=c++11 -O0 -g3 -Wall -c -fmessage-length=0 -o cast.o "..\\cast.cpp"
..\cast.cpp:在函数“int main()”中:
..\cast.cpp:29:43: 错误:“BBslider”是“BB_ival_slider”的不可访问基础
BBslider* pbb2 = dynamic_cast(p);
^
..\cast.cpp:29:43: 错误:“BBslider”是“BB_ival_slider”的不可访问基础

我认为 dynamic_cast 至少应该返回 nullptr。书错了吗?我正在使用 GCC 4.9.2。

【问题讨论】:

  • 受保护的继承是什么意思?只需使用公共继承和聚合。让生活更轻松

标签: c++ c++11 casting


【解决方案1】:

这里的dynamic_caststatic_cast没有区别,编译器发现用户代码试图访问一个受保护的基址,这是非法的。 dynamic_cast 不会隐藏或推迟任何编译时错误。如果在编译时可以确定强制转换是非法的,编译器将永远不会生成任何代码并依赖您在运行时检查强制转换是否确实不正确。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-13
    • 2017-02-21
    • 2012-01-23
    • 2012-09-27
    • 1970-01-01
    • 1970-01-01
    • 2015-09-05
    相关资源
    最近更新 更多