Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 学习C++;:多态性与切片_C++_Polymorphism - Fatal编程技术网

C++ 学习C++;:多态性与切片

C++ 学习C++;:多态性与切片,c++,polymorphism,C++,Polymorphism,考虑以下示例: #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

考虑以下示例:

#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();
}
但我认为输出肯定应该是“生树皮树皮树皮”。那坏蛋怎么了


更新:您可能感兴趣。

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

Dog()
创建一个
Dog
对象。如果您要调用
Dog().makeSound()
,它将按您的预期打印“树皮”

问题是您正在使用此
初始化
坏狗
,它是
动物
类型的对象。由于
动物
只能包含
动物
而不能包含任何源于
动物
的内容,因此它会获取
动物
部分,并使用该部分对自身进行初始化

badDog
的类型总是
Animal
;它不可能是别的东西

<> P>你在C++中可以获得多态行为的唯一方法是使用指针(正如你用<代码> GooDoo[</代码>示例]演示的那样)或使用引用。p> 引用(例如,
动物&
)可以引用从
动物
派生的任何类型的对象,指针(例如,
动物*
)可以指向从
动物
派生的任何类型的对象。然而,普通的
动物
,总是
动物
,没有别的

一些语言如Java和C#具有引用语义,其中变量(在大多数情况下)只是对对象的引用,因此给出了
Animal-rex
rex
实际上只是对一些
动物的引用,而
rex=new Dog()
使
rex
引用一个新的
Dog
对象

C++不工作:变量不引用C++中的对象,变量是对象。如果在C++中说<代码>雷克斯=DOGER()/CUT>,它将新的<代码>狗< /C>对象复制到<代码>雷克斯< /C>中,并且由于雷克斯实际上是类型<代码>动物< /代码>,它被切片,并且只是<代码>动物< /代码>部分被复制。这些被称为值语义,这是C++中的默认值。如果你想在C++中引用语义,你需要显式使用引用或指针(这两个都与C语言或java中的引用相同,但是它们更相似)。 当您实例化一只

并通过值将其分配给
动物
变量时,您将创建对象。这基本上意味着您从
badDog
中去掉所有
Dog
-ness,并将其放入基类


为了对基类使用多态性,必须使用指针或引用。

您使用赋值运算符初始化了badDog。因此,狗()被复制为动物。程序的输出是正确的。:)

我认为您的变量有一些命名错误。代码甚至不能按原样编译。和
void main()???呃……我不明白为什么有人会否决这个问题——它既不是“不清楚”也不是“没用”+1否定否决票。准则“使非叶类抽象化”将防止这一意外。另一个+1用于发布一个完整的、说明问题的最小示例。这正是我们一直要求的。很好的解释。谢谢我将补充说,我已经大大简化了java和C++和C++的类型系统之间的比较。为什么C++对象分配不将VPTR与其余成员一起复制,以获得变量级的PoyLististic?
rawr
bark
rawr
bark
 Animal badDog = Dog();
    ad.makeSound();