我正在研究什么时候/为什么对象切片是危险的。对象切片:pass通过值导出为基础 - 安全还是危险?
我读了一个关于what is safe slicing VS dangerous slicing的好链接。
这里是我可以总结一下(粗略地说): -
- 安全当基类型是值(例如
A
)。 - 危险当基础类型是参考(例如
A&
)。
读之后,我在Visual Studio中 + ReSharper的(一个VS插件)创建的测试代码。
我觉得我的情况是安全。但是,我在标记线#1
处收到警告。
衍生自C类可能无意对象切片值初始化
class B1{ int field1=0; };
class B2{ int field2=0; };
class C: public B1,public B2{ };
class Test{
void f(B1 b){ } #2
void f2(){
C c;
f(c);
//^ possibly unintended object slicing #1
}
};
ReSharper的行为在从我相信一个矛盾的方式。
- 警告当类型为值。
- 无警告当类型是参考(更改#2从
B1
到B1&
)。 - 总是没有警告当
C
只从B1
派生,无论#2
是。 (B
或B&
)
它可以被归纳为一个表: -
| #2=B1 | #2=B1&
==================================================
multi-inherit | warn* | no-warn*
--------------------------------------------------
inherit only from B1 | no-warn | no-warn
然而,这里是我想到: -
| #2=B1 | #2=B1&
===================================================================
multi-inherit | safe* | dangerous*
-------------------------------------------------------------------
inherit only from B1 | safe | safe
不一致刻度*
。
难道我误解了对象切片,或者是Resharper错?
实际上,如果使用[指针或引用]指定值时,切片只能是一个问题(https://stackoverflow.com/questions/15188894/why-doesnt-polymorphism-work-without-pointers-references)你的对象不会切片,并且会正确地表现为多态。 – CoryKramer
(编辑)好点!你似乎是对的......我现在明白了。谢谢! – javaLover
@CoryKramer如果您愿意,您可以发布解决方案。 :) – javaLover