是否存在切片的危险
result Compare(const Osp::Base::Object &obj1, const Osp::Base::Object &obj2, int &cmp) const {
cmp = ((const Block)obj1).NumSuperBlocks() - ((const Block)obj2).NumSuperBlocks();
}
其中
class Block : Object {/*Filler*/}
并确保obj1
和obj2
为Block
个对象?
我很想使用:
cmp = ((const Block*)&obj1)->NumSuperBlocks() - ((const Block*)&obj2)->NumSuperBlocks();
但在阅读SO的对象切片标签的简要描述时,我很想使用前者。但我真的不想要任何讨厌的无声切片。
答案 0 :(得分:7)
引用和指针都是多态的。
您可能更喜欢
static_cast<const Block&>(obj1).NumSuperBlocks()
对于从引用开始的向下转换,它相当于*static_cast<const Block*>(&obj1)
。
答案 1 :(得分:1)
首先,不要使用C风格的演员阵容进行向下转换(或任何演员阵容)。这非常危险,因为它绕过了所有编译器检查。
也就是说,当你向下转换引用或指针时,你不必担心切片。
对于多态对象(即具有虚方法的对象),您可以使用动态强制转换,它为您提供编译时+运行时检查(向下转换指向错误类型的指针时返回null,或在向下转换引用时抛出bad_cast异常错误的类型):
Block & block = dynamic_cast<Block&>(obj);
对于非多态对象,您可以使用static_cast
。