在 C++ 中投射时的对象切片
Posted
技术标签:
【中文标题】在 C++ 中投射时的对象切片【英文标题】:Object slicing while casting in C++ 【发布时间】:2017-04-23 07:16:00 【问题描述】:向下投射时如何进行静态投射会导致对象切片?就像下面的例子一样;
class Parent // base class
public:
virtual void draw();
;
class Child: public Parent //derived class
public:
void draw()
static_cast<Parent>(*this).draw();
// do other stuff
;
【问题讨论】:
您在寻找dynamic_cast<Parent*>(this)->draw()
吗?在这种情况下,您可能需要应用 non-virtual interface idiom(也是 Effective C++ 中的第 34 条)。
执行隐式向上转换 (Parent::draw() ) 解决了这个问题。
这不是隐式的向上转换,也不是任何类型的转换。你只需用一个完全限定的名称来调用它。
要求派生类方法实现来调用基类实现是糟糕的 OOP 设计(在任何编程语言中)。非虚拟接口习惯用法是一个更好的解决方案,其原因在于编译器可以捕获丢失的函数覆盖,但不能捕获丢失的函数调用。
【参考方案1】:
你不是在低调,你是在高调(有点)。
它会导致切片,因为static_cast<Parent>(*this)
通过复制*this
创建了一个新的临时Parent
对象。它基本上等同于以下内容:
Parent*this.draw();
按照 C++ 标准:
[expr.static.cast/1]
表达式 static_cast(v) 的结果是将表达式 v 转换为 T 类型的结果。如果 T 是左值引用类型或对函数类型的右值引用,则结果是左值;如果 T 是对对象类型的右值引用,则结果是 xvalue; 否则,结果是prvalue。 static_cast 运算符不应抛弃常量。
[basic.lval/1.2]
...
prvalue 是一个表达式,其求值初始化对象或位域,或计算运算符的操作数的值,由其出现的上下文指定。...
【讨论】:
以上是关于在 C++ 中投射时的对象切片的主要内容,如果未能解决你的问题,请参考以下文章