c++ - 为什么会出现切片?

标签 c++ variables object memory object-slicing

<分区>

请考虑以下代码:

Base b;
if (something)
    b = DerivedA();
else
    b = DerivedB();

众所周知,在这种情况下会发生“切片”:在 C++ 中,我们不能将基类型的变量分配给派生类型的对象;该对象将被“切片”掉基类型中未定义的任何内容。 (如果我们想做这样的事情,我们必须使用指针或引用)。

我想了解这个的实际原因。即,Base 变量在不切片的情况下无法保存 Derived 对象的原因。

我的假设是,这样做的原因是 Base 对象和 Derived 对象的大小可能不同,因此我们无法保证能够将整个 Derived 对象存储在 Base 变量中。 Base 可能占用 4 个字节,而 Derived 可能占用 7 个字节。因此,我们决定始终对派生对象进行切片以适应基本类型的大小。

我们能够用指针来做到这一点,因为它们都占用相同数量的内存。

这个假设是否正确?如果不是,切片的实际原因是什么?

最佳答案

没有。在您的示例中,切片的原因不同。

Base b; 行中,您在堆栈上为 Base 类型的对象分配了空间,并且已经调用了它的默认构造函数。因此,在 if 语句的每个分支中,发生的是对 b赋值,这是通过赋值运算符实现的,通常带有签名 Base::operator=(const Base&)。如果不重载此运算符,其默认语义是逐字段复制。请注意,参数类型是 Base(或 const Base&),因此只有右侧的 Base 字段可见!

假设您某种方法可以将 DerivedA 对象中包含的所有信息存储在 Base 对象中(尽管这不太可能),您可以将您的赋值运算符重载为 Base::operator=(const DerivedA&),实现您自己的赋值语义,并且上面的方法可以很好地工作。

关于c++ - 为什么会出现切片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26414622/

相关文章:

c# - 参数依赖查找中的混淆?

python - 如何在Python中检查没有输入

c++ - 指针变量有什么用?

c++ - C/C++ fast 两个系列的绝对区别

c - 在文件范围内可变修改的数组和下标值既不是数组也不是指针

python - 程序问题

php - 克隆如何创建单例的新版本?

c++ - 对于虚函数,在声明为虚函数和未声明为虚函数时访问某些方法时会发生什么

javascript - 使用 typescript 合并对象

c++ - codeblocks c++ 停止工作可能是由于引用