C++ C++;遗产对象调用超类方法而不是它自己的方法?

C++ C++;遗产对象调用超类方法而不是它自己的方法?,c++,polymorphism,C++,Polymorphism,所以我有两门课 class Animal{ public: Animal(int age, int hairCount) { howOld = age; numOfHairs = hairCount; } void print(){ cout << "Age: " << howOld << "\tNumber of Hairs: " << numOfHairs <<

所以我有两门课

class Animal{
public:
    Animal(int age, int hairCount) {
        howOld = age;
        numOfHairs = hairCount;
    }

    void print(){
        cout << "Age: " << howOld << "\tNumber of Hairs: " << numOfHairs << endl;
    }

protected:
    int howOld;
    int numOfHairs;
};



class Bird: public Animal{
public:
    Bird(int age, int hairCount, bool fly) : Animal(age, hairCount) {
        canItFly = fly;
    }

    void print() {
        cout << "Age: " << howOld << "\tNumber of Hairs: " 
             << numOfHairs << "\tAbility to fly: " << canItFly << endl;
    }
protected:
    bool canItFly;
};
类动物{
公众:
动物(国际年龄、国际发型){
多少岁=年龄;
numOfHairs=头发计数;
}
作废打印(){

cout您应该声明一个成员函数

void print()
虚拟的,即

virtual void print()
另外,你应该创建一个指向动物的指针向量

vector<Animal *>

根据Benjamin Lindley的建议,您可以选择使用一个智能指针类。

您不能对静态类型的对象执行多态性。您需要使用指针或引用。尝试使用
向量来避免内存管理问题。

您刚刚遇到了对象切片:)


正如其他人所说,你不能静态地声明一个动物数组,因为它只会留出足够的空间来存储动物,像鸟类这样的东西会被切成薄片。

多态性只影响引用和指针

Bird bibo;
Crocodile claus;

Animal & a1 = bibo, & a2 = claus;

a1.print();
a2.print();
仅仅拥有一个泛型的
动物a
并不能让你获得任何多态行为,事实上,它甚至可能没有意义:因为每种动物都是某种类型的具体动物,你的基类可能应该是抽象的

那么容器呢?由于从基类派生的具体类可以具有可变的大小,因此无法将它们直接放入容器中。相反,应该将指向基类的指针指向容器中

选择的指针是
std::unique_ptr
,这是一种轻量级的、最简单的生命周期管理形式。其工作原理如下:

#include <vector>
#include <iostream>
using namespace std;

int main() {
    vector<Animal> list;
    list.pushBack(Bird(5,10000,true));
    list.pushBack(Animal(14,1234567));

    for(int i = 0; i < list.size(); i++){
        list[i].print(); //Calls the super class for both outputs
    }
    return 0;
}
#include <memory>
#include <vector>

typedef unique_ptr<Animal> AnimalPtr;
typedef std::vector<AnimalPtr> Zoo;

Zoo z;

z.push_back(AnimalPtr(new Bird));   // old-style
z.emplace_back(new Crocodile);      // new-style, better

编辑:我遗漏了那个小细节。我确实在超类上有虚函数。不确定它为什么不打印。我不能在这样声明向量之后使用list[I].print()调用print方法。如果基函数是,重写函数将自动
virtual
。@Chickeneatergy:然后像这样调用它:
list[I]->print()
您需要在超类的每个方法中添加关键字“virtual”,以便子类重写。在中也是如此。+1。是的。相反,您必须声明对动物的引用数组(或指向动物的指针)。是的,我也忘了这一点!
Bird bibo;
Crocodile claus;

Animal & a1 = bibo, & a2 = claus;

a1.print();
a2.print();
#include <memory>
#include <vector>

typedef unique_ptr<Animal> AnimalPtr;
typedef std::vector<AnimalPtr> Zoo;

Zoo z;

z.push_back(AnimalPtr(new Bird));   // old-style
z.emplace_back(new Crocodile);      // new-style, better
struct Animal
{
  virtual void print() const = 0;
  // ...
};
void Animal::print() const
{
  out << "Age: " << howOld << "\tNumber of Hairs: " << numOfHairs << endl;
}

struct Bird
{
  virtual void print() const
  {
    Animal::print();  //  call base function first
    cout << "Ability to fly: " << canItFly << endl;
  }
  // ...
};