C++ 从C+动态引发怀疑+/Stroustrup:转换为受保护的基类

C++ 从C+动态引发怀疑+/Stroustrup:转换为受保护的基类,c++,inheritance,dynamic-cast,C++,Inheritance,Dynamic Cast,我知道以下代码给出了编译错误: 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*&

我知道以下代码给出了编译错误:

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

classa{public:virtualvoid name(){cout也许他测试了那段代码,也许没有(很多作者在书中都放了未测试的代码。)如果他真的测试了它,请记住并非所有的编译器都是平等的。g++失败的原因是
错误:“BBslider”是“BB\u ival\u slider”的不可访问的基。
。clang失败的原因是
错误:无法将“BB\u ival\u slider”强制转换到其受保护的基类“BBslider”
。其他编译器:谁知道?我所知道的每个编译器都有一些co方面的问题遵守标准。

我想如果我没有找到任何建设性的证据,那么我可以说

“Stroustrup错了”(听起来很可怕:()


我认为编译器是不允许随意(按照定义的标准)泄露类内部的秘密的。除非他们通过刀子。(即邪恶的指针操作)

15.4.1中的实际引用是:

class BB_ival_滑块:公共ival_滑块,受保护的bbs滑块{
// ...
};
空f(BB_ival_滑块*p)
{
Ival_滑块*pi1=p;//确定
Ival_滑块*pi2=动态_投射(p);//确定
BBslider*pbb1=p;//错误:BBslider是受保护的基址
BBslider*pbb2=dynamic_cast(p);//确定:pbb2变为0
}
这是一个令人不感兴趣的案例。但是,知道
dynamic\u cast
不允许意外违反私有和受保护基类的保护是令人放心的

因此,描述代码的文本似乎是正确的,但出于错误的原因--
dynamic_cast
不允许意外违反对私有和受保护基类的保护,这只是因为使用它会导致格式错误并导致编译器错误,而不是因为使用它会产生错误当然,文本描述的代码肯定是不正确的

错误会发生——也许会在本书的第四版中修复。:-]


(另外,请注意,如果
BB_ival_slider
声明
f
朋友
,那么代码将按照书中所述的方式运行。也许这一
朋友
声明是在本章前面暗示的,但我现在没有时间仔细阅读它以检查其中一种方式或另一种方式。)有趣的问题-注意,即使基类是虚拟的,这个子类也会失败,并且子类通过同一个基础从代码>公共虚< /代码>派生……我想看到C++编译器为什么可以拒绝这个引用。我很懒。(我通常遵循Stroustrup的单词作为标准。)但我认为有必要为这样一种生动的语言打开世界上最枯燥乏味的标准报告。@bdonlan:5.2.7第5段,关于
dynamic\u cast(指向D类的指针)
,“
B
应该是
D
的一个可访问的明确基类”(我的重点)@戴维,如果B不是D的基类,那么C是从B和A派生出来的,我们应该能够动态地从B*到C的实例,或者是它的基类,或者是它的C超类。(这就是这个问题的上下文)。该段以“如果
T
是“指向
cv1b
”和
v
具有类型“指向
cv2d
”开头,因此
B
D
的基类,…”.5.2.7第8段介绍了通过
dynamic\u cast
进行向下转换。嗯,我们在这里讨论的是stroustrup……标准反映了他的想法。反之亦然。:PBy“邪恶指针操作”,我想你指的是邪恶的C样式转换。是的,C样式转换可以将派生类指针转换为基类指针,“即使基类类型不可访问”(5.4第7段)。这个邪恶操作的结果不是空指针。@David是的,是的。这种c风格的黑魔法没有治愈方法。:)如果有人使用过它,那么只有“施放”的人"只有它才能可靠地撤销它。呵呵,我很想找到你用来从书中复制内容的任何东西。你有什么?PDF还是一些电子书?@Ajeet:我看了看我的硬拷贝,把它打印出来,因为它很短。如果我有一本电子书,我可以在这一章中搜索单词
friend
,然后回答问题r我在最后一段中提到过。.-]酷,你是我喜欢的类型,他会让斯特劳斯特站在自己的桌面上伸手可及的地方?@Ajeet:的确,总是,还有萨特、梅耶斯和约瑟蒂斯的书。.-]萨特很好。那家伙可以找到不明显和几乎不可察觉的东西。但你有没有在斯特劳斯特站起来后再提到梅耶斯呢?:)
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
}
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
}