学习C ++:多态和切片 [英] Learning C++: polymorphism and slicing
问题描述
请考虑以下示例:
#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屋!