2011-03-20 137 views
5

当我继续继承和上/下铸造时,我偶然发现了这个问题。为什么不允许(代码被注释为显示不允许的部分)?现在我可以猜测为什么它不被允许,但事实上的答案会很好。受保护/私有继承铸造

至于那允许的代码,我知道那是因为(基地*)是C样式转换本质上是一个的reinterpret_cast在C++这反过来又意味着,在这种情况下,它会导致未定义的行为。如果我错了,请纠正我。

class Base 
{ 
}; 

class Derived : public Base 
{ 
}; 

class DerivedProt : protected Base 
{ 
}; 

class DerivedPriv : private Base 
{ 
}; 

int main() 
{ 
    Base* a = new Derived(); 
    Base* b = new DerivedProt(); // Not allowed 
    Base* c = new DerivedPriv(); // Not allowed 

    Base* d = (Base*) new DerivedProt(); // Allowed but undefined behavior...? 
    Base* e = (Base*) new DerivedPriv(); // Allowed but undefined behavior...? 
} 

回答

0

听起来像你是对的。

需要记住的一件事是传统的面向对象的原则,如LSP只描述公共继承。非公有继承属于继承和组合之间,基础子对象是非公开的组合,但您也可以利用依赖于继承的功能(例如虚拟功能)。

但是,就像组合的子对象一样,只有类(或其后代,在受保护继承的情况下)才能获得子对象的地址。

6

该标准明确指定C风格转换可以执行此转换。这是C风格投下的唯一角色,可以做,但没有C++演员能做。据我所知,结果并不确定;这仅仅是其他演员所不允许的。

+1

即使它不是未定义的行为,它仍然是一个令人难以置信的坏主意,应该避免。这种转换非常危险的一件事是,即使没有继承关系并且甚至不会产生警告,编译器也会尝试去做。 – 2011-03-20 23:11:09

+5

我不得不在线查看Comeau,看看我的编译器是否得到了这个错误。不,reinterpret_cast <>也可以这样做。 – 2011-03-21 00:31:54

+0

@HansPassant但是'reinterpret_cast'不知道或关心基类。它不能用于向上或向下演员。 – curiousguy 2011-12-19 16:05:52