![]() |
1
21
在C++中,应该将对象切片视为 转换 从派生类型到基类型[*]。一个全新的对象被创造出来,这是“一个真实故事的启发”。 有时这是你想做的事情,但结果在任何意义上都不是原来的对象。当对象切片出错时,就是人们不注意的时候,认为它是同一个对象或它的副本。 这通常是不有益的。事实上,这通常是意外的,当某人通过值时,他们打算通过引用。 很难想出一个例子,说明何时切片是正确的事情,因为很难(特别是C++)提出一个非抽象基类是绝对正确的例子。这是一个重要的设计点,不能轻易忽略——如果您发现自己有意或无意地切割了一个对象,很可能您的对象层次结构是错误的。要么基类不应用作基类,要么它至少应具有一个纯虚拟函数,因此不能按值进行切片或传递。 所以,我举的任何一个例子,如果一个对象被转换成它的基类对象,都会引起反对,“等等,你从一个具体的类继承了什么?”如果切片是偶然的,那么它可能是一个bug,如果是故意的,那么它可能是“代码气味”。 但答案可能是“是的,好的,这个 不应该 真的是事情的结构,但考虑到它们 是 这样的结构,我需要从派生类转换为基类,并且根据定义,这是一个切片”。本着这种精神,这里有一个例子:
现在,要求
activesoldier是另一种类型。出于仅为该类的作者所知的原因,它选择公开地从士兵继承,而不是提供重载的转换运算符。我们可以争论这是否是一个好主意,但假设我们一直坚持下去。因为它是派生类,所以可以转换为士兵类。这种转换称为切片。因此,如果我们打电话
您可能会为一个输出器想出类似的例子,在这个例子中,接收者只关心被传递的对象的基类部分,因此允许在将对象写入迭代器时对它们进行切片。
它的“代码气味”是因为我们应该考虑(a)重写activesoldier,和(b)更改士兵,以便使用函数而不是成员访问来访问它,这样我们就可以将这组函数抽象为其他类型可以独立实现的接口,以便
因为它是一个。下面最后两行是做同样的事情:
唯一的区别是(1)调用的是A的复制构造函数(编译器提供的,即使代码不提供),而(2)调用的是A的int构造函数。
正如其他人所说的,Java不做对象切片。如果您提供的代码被转换为Java,则不会发生任何对象切片。Java变量是引用而不是对象,所以后置条件是
您可以使用指针或引用在C++中获得类似Java的效果:
事实上,我哥哥不是牧师。 |
![]() |
James Ko · 为什么。loc对切片具有包容性行为? 7 年前 |
![]() |
vaanchit kaul · python中的切片列表 7 年前 |
|
Nikunj Patel · 如何将字符串转换为字符串数组 7 年前 |
![]() |
Josh · 从矩阵中高效提取特定数据 7 年前 |
![]() |
NI6 · 迭代从特定键开始的有序dict项 7 年前 |
|
user9316622 · Python中的字典切片和求和 7 年前 |