在c++中,什么是对象切片,什么时候发生?


当前回答

切片意味着当子类的对象通过值或从期望基类对象的函数传递或返回时,子类添加的数据将被丢弃。

说明:考虑以下类声明:

           class baseclass
          {
                 ...
                 baseclass & operator =(const baseclass&);
                 baseclass(const baseclass&);
          }
          void function( )
          {
                baseclass obj1=m;
                obj1=m;
          }

由于基类复制函数不知道派生的任何信息,因此只复制派生的基部分。这通常被称为切片。

其他回答

所以为什么丢失派生信息很糟糕。。。因为派生类的作者可能已经改变了表示方式,使得分割额外信息改变了对象所表示的值。如果派生类用于缓存对某些操作更有效但转换回基表示代价高昂的表示,则会发生这种情况。

还认为有人应该提到你应该做什么来避免切片。。。获取C++编码标准、101条规则指南和最佳实践的副本。处理切片是#54。

它提出了一种有点复杂的模式来完全解决这个问题:有一个受保护的复制构造函数、一个受受保护的纯虚拟DoClone,以及一个带有断言的公共克隆,如果(进一步)派生类未能正确实现DoClone,该断言将告诉您。(克隆方法对多态对象进行适当的深度复制。)

您还可以在基显式上标记复制构造函数,如果需要,它允许显式切片。

好的,在阅读了许多解释对象切片的文章后,我会尝试一下,但不知道它是如何变得有问题的。

可能导致内存损坏的恶性场景如下:

类在多态基类上提供(意外地,可能是编译器生成的)赋值。客户端复制并切片派生类的实例。客户端调用一个虚拟成员函数,该函数访问切片状态。

切片意味着当子类的对象通过值或从期望基类对象的函数传递或返回时,子类添加的数据将被丢弃。

说明:考虑以下类声明:

           class baseclass
          {
                 ...
                 baseclass & operator =(const baseclass&);
                 baseclass(const baseclass&);
          }
          void function( )
          {
                baseclass obj1=m;
                obj1=m;
          }

由于基类复制函数不知道派生的任何信息,因此只复制派生的基部分。这通常被称为切片。

谷歌第三次匹配“C++切片”给了我这篇维基百科文章http://en.wikipedia.org/wiki/Object_slicing这(很热,但前几篇文章定义了问题):http://bytes.com/forum/thread163565.html

因此,当您将子类的对象分配给超级类时。超类对子类中的附加信息一无所知,并且没有空间存储它,因此附加信息被“分割”。

如果这些链接没有提供足够的信息来获得“好答案”,请编辑您的问题,让我们知道您还需要什么。

在C++中,派生类对象可以分配给基类对象,但另一种方式是不可能的。

class Base { int x, y; };

class Derived : public Base { int z, w; };

int main() 
{
    Derived d;
    Base b = d; // Object Slicing,  z and w of d are sliced off
}

当派生类对象分配给基类对象时,对象切片发生,派生类对象的其他属性被切片以形成基类对象。