学习C ++:多态和切片 [英] Learning C++: polymorphism and slicing

查看:114
本文介绍了学习C ++:多态和切片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下示例:

#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。

But I thought that surely the output should be "rawr bark bark bark". What's with the badDog?

更新:您可能对我的另一个问题

推荐答案

这是一个名为切片的问题。

This is a problem called "slicing."

Dog() c $ c> Dog 对象。如果你打电话 Dog()。makeSound(),它会打印bark,如你所期望的那样。

Dog() creates a Dog object. If you were to call Dog().makeSound(), it would print "bark" as you expect it to.

问题是你正在初始化 badDog ,这是一个 Animal 类型的对象, code> Dog 。由于 Animal 只能包含 Animal ,而不是源自 Animal ,它需要 Dog 部分,并用此初始化。

The problem is that you are initializing the badDog, which is an object of type Animal, with this Dog. Since the Animal can only contain an Animal and not anything derived from Animal, it takes the Animal part of the Dog and initializes itself with that.

badDog 的类型始终为 Animal ;

你可以在C ++中获得多态行为的唯一方法是使用指针(如你在 goodDog example)或使用引用。

The only way you can get polymorphic behavior in C++ is using pointers (as you have demonstrated with your goodDog example) or using references.

引用(例如, Animal& )可以引用源自 Animal 和指针(例如, Animal * )可以指向从 / code>。一个简单的 Animal ,总是一个 Animal ,没有别的。

A reference (e.g., Animal&) can refer to an object of any type derived from Animal and a pointer (e.g., Animal*) can point to an object of any type derived from Animal. A plain Animal, however, is always an Animal, nothing else.

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

Some languages like Java and C# have reference semantics, where variables are (in most cases) just references to objects, so given an Animal rex;, rex is really just a reference to some Animal, and rex = new Dog() makes rex refer to a new Dog object.

C ++不会这样工作:变量不引用C ++中的对象,变量是对象。如果你在C ++中说 rex = Dog(),它会将一个新的 Dog 对象复制到 rex ,因为 rex 实际上是类型 Animal ,它被切片, Animal 零件被复制。这些被称为值语义,这是C ++中的默认语义。如果你想在C ++中引用语义,你需要明确使用引用或指针(这两个都不是相同的引用在C#或Java,但他们更相似)。

C++ doesn't work that way: variables don't refer to objects in C++, variables are objects. If you say rex = Dog() in C++, it copies a new Dog object into rex, and since rex is actually of type Animal, it gets sliced and just the Animal parts get copied. These are called value semantics, which are the default in C++. If you want reference semantics in C++, you need to explicitly use references or pointers (neither of these are the same as references in C# or Java, but they are more similar).

这篇关于学习C ++:多态和切片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆