c++ - 对象切片: pass Derived as Base by value - safe or dangerous?

标签 c++ resharper object-slicing

我正在研究对象切片何时/为何是危险的。

我读到了一个关于 what is safe slicing VS dangerous slicing 的精彩链接.
以下是我可以总结的内容(粗略地说):-

  • 安全,当基本类型为时(例如A)。
  • 危险,当基本类型为引用时(例如A&)。

读完后,我在 Visual Studio + Resharper(VS 插件)中创建了一个测试代码。
我认为我的情况是安全。但是,我在标记行 #1 处收到警告。

possibly unintended object slicing value-initialized from derived class 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 是什么,始终无警告。 (BB&)

它可以总结成一个表格:-

                      |    #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错了?

最佳答案

Resharper acts in a contradict way from my belief.

它以正确的方式运行,让我们看看:

Warning when the type is value.

这是这个代码:

class B1{ int field1=0; };  
class B2{ int field2=0; };
class C: public B1,public B2{    };
class Test{
    void f(B1 b){ }
    void f2(){
        C c;
        f(c);
      }
};

在函数调用中,从 C 类型的变量 c 初始化 B1 类型的变量 b 的值派生自B1,会执行B1的一个拷贝构造函数,其签名为B1(const B1& rhs);,在这个构造函数中(无论是它是否自动生成)只有 B1 中存在的字段将从 rhs 复制,因此其余部分(来自 B2 C) 将被切片。

No warning when the type is reference (change #2 from B1 to B1&).

void f(B1& b){ } 

这是正确的,这就是通过将对象分配给基类类型的指针或引用来传递多态对象的方式。

Always no warning when C derived from only B1, no matter #2 is. (B or B&)

那只是因为C没有字段,所以在这种情况下没有切片。尝试将 int n; 添加到 C 中,警告将再次显示。

关于c++ - 对象切片: pass Derived as Base by value - safe or dangerous?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42649052/

相关文章:

c++ - 简单的 cout 然后 cin 允许空格示例?

C++ 刽子手游戏

c++ - 传递继承引用类型时切片或不切片

c++ - 模板编译器错误 - 未引用值

c++ - 无法杀死 std::thread

c# - 只使用方法的实现?

regex - Resharper 9 中内联字符串的正则表达式语法突出显示信息存储在哪里?

c# - Resharper 关闭类型提示

C++ 防止在 std::vector 中进行对象切片

c++ - 如何在单个 vector 中存储不同的类?