c++ - 派生类的切片是如何发生的?

标签 c++ oop inheritance polymorphism pass-by-reference

我无法理解切片是如何发生的?例如,在这段代码中:

class A {
public:
  virtual h() {
    cout << "type A" << endl;
  }
};

class B : public A {
public:
  virtual h() override {
    cout << "type B" << endl;
  }
};

void f(A a) {
  a.h();
}

void g(A& a) {
  a.h();
}

int main() {
  A a1 = B(); // a1 is A and doesn't recognize any B properties
  A *a = new B();
  f(*a);
  g(*a);
}

我注意到:

  1. 变量 a1 不知道它是 B,但变量 a 知道。我认为发生这种情况是因为在变量 a1 中,对 B 的赋值是按值进行的,与变量 a 不同,我在变量 a 中创建了一个指向 B 的指针。

  2. 当我将变量 a 传递给不同的函数时,也会发生同样的情况 - 当我按值传递时,它认为它是 A,但当我按引用传递时,它认为它是 B。

如果有人能给我更广泛、更深入的解释,我会很高兴。预先感谢您!

最佳答案

  1. variable a1 doens't know it's a B

更准确地说:变量 a1 被声明为 A,因此它是 A。它不是 B,也从来不是 B。这与变量“知道”什么无关;而是关于变量 a1 被声明为 A。这是关于变量的类型。 a1 是通过“切片”基础子对象的拷贝从 B 初始化的。

I would be happy if anyone could give me more extensive and deeper explanation.

间接对于运行时多态性是必要的。 A 类型的对象始终是 A 类型,而不是其他类型。这就是语言中类型的简单形式。原因之一是编译器必须知道对象需要多少内存。如果编译器为 A 保留内存,那么可能更大的派生实例如何适合保留的内存?

但是指向 A 的指针(或引用)可以指向不同的 A 对象,也可以指向从 A 派生的类的基子对象。完整的对象有多大并不重要,无论如何,指针都可以指向对象的一部分,并且这不会影响指针本身的大小。

how slicing of derived classes occurs?

每当将派生对象转换为基类型时,就会发生切片。该转换复制基类子对象。请注意,当您将派生值转换为对基类的引用时,不会发生切片 - 除非您使用该引用来初始化基类类型的对象。

关于c++ - 派生类的切片是如何发生的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58009142/

相关文章:

c++ - 返回 boost multi_index 接口(interface)时 C++ 中的 const 混淆

c++ - 在 C++ 中,编译器如何处理对模板的调用?

c++ - LLVM C++ 和 GNU C++ 的标准库具有不同的 header

javascript - 结合数组和字典属性的数据类型

c# - 可以静态分析重写的方法吗?

c# - 用更多的派生类型覆盖子类继承的属性

c++ - 引用限定符和删除的成员方法

python - 为什么我的 python 类继承不正确?

inheritance - 如何将 struct 方法的访问权限授予 Go 中的嵌入式方法?

oop - OO设计封装