在 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&lt;Parent*&gt;(this)-&gt;draw()吗?在这种情况下,您可能需要应用 non-virtual interface idiom(也是 Effective C++ 中的第 34 条)。 执行隐式向上转换 (Parent::draw() ) 解决了这个问题。 这不是隐式的向上转换,也不是任何类型的转换。你只需用一个完全限定的名称来调用它。 要求派生类方法实现来调用基类实现是糟糕的 OOP 设计(在任何编程语言中)。非虚拟接口习惯用法是一个更好的解决方案,其原因在于编译器可以捕获丢失的函数覆盖,但不能捕获丢失的函数调用。 【参考方案1】:

你不是在低调,你是在高调(有点)。

它会导致切片,因为static_cast&lt;Parent&gt;(*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++ 中投射时的对象切片的主要内容,如果未能解决你的问题,请参考以下文章

C++ 构造函数成员初始化器列表,对象切片

什么是对象切片?

什么是对象切片?

什么是对象切片?

8-2:C++继承之父类和子类对象赋值转换(公有继承)也即切片

在 C++ 中切片 char 数组(python 到 c++)