![]() |
1
15
如果可以修改基类,可以执行以下操作:
取决于您的编译器,它应该为您提供翻译单元,也可能是发生切片的函数。 |
![]() |
2
8
作为 Andrew Khosravian's answer ,我建议使用模板化的复制构造函数和赋值运算符。这样,您就不需要知道给定基类的所有派生类,从而保护该基类不受切片的影响:
虽然这减少了所需的工作量,但是使用这种方法,您仍然需要处理每个基类以保护它。此外,如果存在合法的转换,它将导致问题
对于世界上的编译器实现者: 测试对象切片绝对是值得为其创建(可选)警告的!我想不出一个例子,它是期望的行为,它在新版C++代码中是很常见的。 [编辑日期:2015年3月27日:] 正如MattMcNab所指出的,实际上您不需要像上面所做的那样显式地声明复制构造函数和赋值运算符,因为编译器仍然隐式地声明它们。在2003 C++标准中,这在脚注106中明确地提到了在128/2:
|
![]() |
3
4
我建议向您的基类添加一个构造函数,它显式地引用派生类(带有一个forward声明)。在我的简单测试应用程序中,这个构造函数在切片情况下被调用。然后,您至少可以得到一个运行时断言,并且您可能通过巧妙地使用模板得到一个编译时断言(例如:以在该构造函数中生成编译时断言的方式实例化一个模板)。在调用显式函数时,也可能有特定于编译器的方法来获取编译时警告或错误;例如,您可以在Visual Studio的“切片构造函数”中使用“u declspec(已弃用)”,以获取编译时警告,至少在函数调用情况下是如此。 因此,在您的示例中,代码如下所示(对于Visual Studio):
这在我的测试中有效(编译时警告)。注意,它并不能解决复制问题,但是一个构造类似的赋值操作符应该在这里完成这个技巧。 希望这有帮助。:) |
![]() |
4
1
这通常被称为 Object Slicing 这是一个众所周知的问题,有自己的维基百科文章(尽管它只是对这个问题的简短描述)。 我相信我已经使用了一个编译器,它有一个警告,您可以通过它来检测和警告这个问题。但是,我不记得是哪一个。 |
![]() |
5
1
不是解决你眼前问题的办法,而是…… 大多数将类/结构对象作为参数的函数都应将参数声明为“const x&或”x&“类型,除非它们有非常好的理由不这样做。 如果总是这样做,对象切片永远不会成为问题(引用不会被切片!). |
![]() |
6
1
解决这个问题的最佳方法通常是遵循斯科特·迈耶的建议(参见 有效C++ )只在继承树的叶节点上有具体的类,并且通过至少一个纯虚拟函数(如果没有其他函数,则是析构函数)确保非叶类是抽象的。 令人惊讶的是,这种方法有助于以其他方式澄清设计。在任何情况下,隔离公共抽象接口的工作通常都是值得的设计工作。 编辑虽然我最初没有明确说明这一点,但我的答案来自这样一个事实,即在编译时不可能准确地警告对象切片,因此,如果您启用了编译时断言或编译器警告,则可能导致错误的安全感。如果您需要了解对象切片的实例,并需要更正它们,那么这意味着您有更改遗留代码的愿望和能力。如果是这样,那么我相信您应该认真考虑重构类层次结构,以使代码更健壮。 我的理由是。 考虑一些库代码,它定义了一个类concrete1,并在这个函数的推理中使用它。
传递类型be引用是为了提高效率,通常是一个好主意。如果库将concrete1视为值类型,则实现可能会决定复制输入参数。
如果传递的引用的对象类型确实是,
考虑一些派生的客户端代码
因为参数是引用获取的,所以在要检查的参数上此处不会发生切片,因此在此处警告切片是不正确的,因为可能不会发生切片。将派生类型传递给接受引用或指针的函数是利用多态类型的一种常见而有用的方法,因此警告或不允许这样做可能会适得其反。 那么哪里有错误呢?好吧,“错误”是传递一个对某个东西的引用,这个东西是从一个类派生出来的,然后被调用的函数将这个类视为一个值类型。 一般来说,没有办法生成一个针对对象切片的持续有用的编译时警告,这就是为什么在可能的情况下,最好的防御是通过设计消除问题。 |
![]() |
7
1
你是说派生是一个基,所以它应该在任何取基的函数中工作。如果这是一个真正的问题,那么继承可能不是你真正想要使用的。 |
![]() |
8
0
我稍微修改了你的代码:
显式关键字将确保构造函数不会用作隐式转换运算符-您必须在要使用它时显式调用它。 |
![]() |
James Ko · 为什么。loc对切片具有包容性行为? 7 年前 |
![]() |
vaanchit kaul · python中的切片列表 7 年前 |
|
Nikunj Patel · 如何将字符串转换为字符串数组 7 年前 |
![]() |
Josh · 从矩阵中高效提取特定数据 7 年前 |
![]() |
NI6 · 迭代从特定键开始的有序dict项 7 年前 |
|
user9316622 · Python中的字典切片和求和 7 年前 |