将对象(而不是指针)向下转换为其已知的派生类型是否安全?
是否存在切片的危险?
result Compare(const Osp::Base::Object &obj1, const Osp::Base::Object &obj2, int &cmp) const {
cmp = ((const Block)obj1).NumSuperBlocks() - ((const Block)obj2).NumSuperBlocks();
}
Where
class Block : Object {/*Filler*/}
和 obj1
和 obj2
确保是 Block
对象?
我很想使用:
cmp = ((const Block*)&obj1)->NumSuperBlocks() - ((const Block*)&obj2)->NumSuperBlocks();
但是在阅读了SO对对象切片标签的简要描述后,我很想使用前者。但我真的不想要任何令人讨厌的无声切片。
Would there be a danger of slicing
result Compare(const Osp::Base::Object &obj1, const Osp::Base::Object &obj2, int &cmp) const {
cmp = ((const Block)obj1).NumSuperBlocks() - ((const Block)obj2).NumSuperBlocks();
}
Where
class Block : Object {/*Filler*/}
and obj1
and obj2
are assured to be Block
objects?
I'm tempted to use:
cmp = ((const Block*)&obj1)->NumSuperBlocks() - ((const Block*)&obj2)->NumSuperBlocks();
but on reading SO's brief description of the object-slicing tag I'm tempted to use the former. But I really don't want any nasty silent slicing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
引用和指针都是多态的。
您可能更喜欢
从引用开始向下转型,它相当于
*static_cast(&obj1)
。References and pointers are both polymorphic.
You may prefer
for downcasting starting with a reference, it's equivalent to
*static_cast<const Block*>(&obj1)
.首先,不要使用 C 风格的强制转换进行向下强制转换(或任何强制转换)。这是非常危险的,因为它绕过了所有编译器检查。
也就是说,当您向下转换引用或指针时,无需担心切片。
对于多态对象(即具有虚拟方法的对象),您可以使用动态强制转换,它为您提供编译时 + 运行时检查(在向下转换指向错误类型的指针时返回 null,或者在向下转换对错误类型的引用时抛出 bad_cast 异常) type):
对于非多态对象,您可以使用
static_cast
。First of all don't use C-style casts for downcasting (or any casting at all). It's very dangerous because it circumvents all compiler checking.
That said, you don't need to worry about slicing when you are downcasting references or pointers.
For polymorphic objects (i.e. objects that have virtual methods) you can use dynamic cast, which gives you compile-time + runtime checking (returns null when downcasting a pointer to the wrong type, or throws a bad_cast exception when downcasting a reference to the wrong type):
For non polymorphic objects you can use
static_cast
.