gpt4 book ai didi

c++ - 学习 C++ : polymorphism and slicing

转载 作者:IT老高 更新时间:2023-10-28 13:59:20 42 4
gpt4 key购买 nike

考虑以下示例:

#include <iostream>
using namespace std;

class Animal
{
public:
virtual void makeSound() {cout << "rawr" << endl;}
};

class Dog : public Animal
{
public:
virtual void makeSound() {cout << "bark" << endl;}
};

int main()
{
Animal animal;
animal.makeSound();

Dog dog;
dog.makeSound();

Animal badDog = Dog();
badDog.makeSound();

Animal* goodDog = new Dog();
goodDog->makeSound();
}

输出是:

rawr
bark
rawr
bark

但我认为输出肯定应该是“rawr bark bark bark”。坏狗怎么了?


更新:您可能对 another question of mine 感兴趣.

最佳答案

这是一个称为“切片”的问题。

Dog() 创建一个 Dog 对象。如果你调用 Dog().makeSound(),它会像你期望的那样打印“bark”。

问题是您正在用这个Dog 初始化badDog,它是一个Animal 类型的对象。由于 Animal 只能包含 Animal 而不能包含任何从 Animal 派生的内容,因此它需要 Animal 部分Dog 并用它初始化自己。

badDog 的类型总是Animal;它永远不会是其他任何东西。

在 C++ 中获得多态行为的唯一方法是使用指针(正如您在 goodDog 示例中所展示的那样)或使用引用。

引用(例如,Animal&)可以引用从 Animal 派生的任何类型的对象和指针(例如,Animal* ) 可以指向从 Animal 派生的任何类型的对象。然而,普通的 Animal 始终是 Animal,仅此而已。

Java 和 C# 等一些语言具有引用语义,其中变量(在大多数情况下)只是对对象的引用,所以给定一个 Animal rex;rex 确实是只是对一些 Animal 的引用,而 rex = new Dog() 使 rex 引用一个新的 Dog 对象.

C++ 不是这样工作的:变量不引用 C++ 中的对象,变量是对象。如果你在 C++ 中说 rex = Dog(),它会将一个新的 Dog 对象复制到 rex 中,并且由于 rex 实际上是 Animal 类型的,它被切片并且只有 Animal 部分被复制。这些被称为值语义,这是 C++ 中的默认值。如果要在 C++ 中使用引用语义,则需要显式使用引用或指针(它们都与 C# 或 Java 中的引用不同,但它们更相似)。

关于c++ - 学习 C++ : polymorphism and slicing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4403726/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com