当我得到一个 `slicing` 的案例时?

When I get a case of `slicing`?

我们看下一段代码(举例):

class A {
    int n;
public:
    int f() const { return n; }
    void set(int i) { n = i; }
};
class B : public A {
public:
    int g() const { return f()+1; }
};
void h(const A& a) {
    a.f();
}
int main() {
    B b;
    A& a = b;
    A* ptrA = new B; 
    h(b);
  delete ptrA;
    return 0;
}

现在,让我们看看这些行代码:

A& a = b; // Is there "slicing"? (why?)
A* ptrA = new B; // Is there "slicing"? (why?)
A a = b; // Is there "slicing"? (why?)

我真的不明白什么时候我想使用它们中的任何一个,或者什么时候不允许您使用它们中的任何一个。这些行之间真正的区别是什么..

切片是指将派生对象分配给基础实例。例如:

B b;
A a = b;

这里的问题是正在调用的 A 的复制构造函数只能看到 BA 部分,因此只会复制它。如果您的派生 class 添加了额外的数据或覆盖了 A 的行为,这就是一个问题。

当您将对象分配给引用或指针时,没有切片。所以

A &a = b;

没问题,就这样:

A *a = &b;