c++继承.对象调用超类方法而不是自己的方法
C++ Inheritance. Object calls super-class method instead of its own method?
我有两个类,
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;
};
如果在主程序中,我有这样的内容:
#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;
}
由于某种原因,我的代码(不是这个)在这两种情况下都调用超类的print方法
你应该声明一个成员函数
void print()
是虚的,即
virtual void print()
除此之外,您还应该创建一个指向Animal的指针向量
vector<Animal *>
在main中使用new创建新对象。然后它会像预期的那样工作。也就是说,你的main应该是这样的
vector<Animal *> list;
Animal *bird = new Bird(5,10000,true);
Animal *animal = new Animal(14,1234567);
list.push_back(bird);
list.push_back(animal);
如果你不再需要鸟类和动物,不要忘记删除
delete bird;
delete animal;
根据Benjamin Lindley的建议,您可以选择使用智能指针类之一。
不能对静态类型对象进行多态性。你需要使用指针或引用。
vector<unique_ptr<Animal>>
以避免内存管理问题。你刚刚遇到了对象切片:)
http://en.wikipedia.org/wiki/Object_slicing就像其他人说的,你不能静态地声明一个动物数组,因为它只会为动物提供足够的空间,而像鸟这样的东西会被切片。
多态性只影响引用和指针:
Bird bibo;
Crocodile claus;
Animal & a1 = bibo, & a2 = claus;
a1.print();
a2.print();
只有一个通用的Animal a
不给你访问任何多态行为,事实上它可能甚至没有意义:因为每个动物都是某种类型的具体动物,你的基类可能应该是抽象的。
那么容器呢?由于派生自基类的具体类可以具有可变大小,因此无法将它们直接放入容器中。相反,应该将指针指向容器中的基类。
选择的指针是std::unique_ptr<Animal>
,它是轻量级的,也是生命周期管理的最简单形式。它是这样工作的:
#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
最后,关于如何使Animal
抽象的一些模糊细节。可以将print()
声明为纯虚值。然而,我们还需要一个基本实现。两者都可以:
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;
}
// ...
};
相关文章:
- 没有为自己的结构调用列表推回方法
- 在他自己的方法中,有可能将一个对象取消引用到另一个对象吗
- 在c++中为我自己的基于指针的数组分配内存的正确方法
- 类无法访问自己的私有静态 constexpr 方法 - Clang bug?
- 在wxWidgets的事件中包含我自己的数据的最佳方法是什么?
- 返回自己的类型的模板类方法的正确签名
- 创建自己的异常(2种方法)C
- make 方法不更改自己的类变量而不使它们常量
- 电子内部或外部方法创建自己的右键单击上下文菜单 - Windows
- 通过我自己的实现从库中覆盖模板方法
- 将C++主方法移动到其自己的文件时发生编译器错误
- ISO禁止启动自己类方法的线程
- OpenCV 未定义引用我自己的库中的方法
- ctypes 自己的库加载,但无法访问函数/方法
- cpp 对象方法是否有自己的堆栈帧
- 为什么无法从模板方法访问此类自己的受保护成员?
- 自己的"Insert"方法(向量)函数模板
- 如何扩展stl类以拥有自己的方法?
- c++继承.对象调用超类方法而不是自己的方法
- 如何在自己的方法中使用lambda表达式