警告:本文是用来学习有关类的知识点,由于初学,所以必会犯很多错误,请大家酌情观看
1、虚方法
#include<iostream>
class Animal
{
public:
void eat();
Animal(std::string Name);
protected:
std::string name;
};
class Dog :public Animal
{
public:
void eat();
Dog(std::string Name);
};
Animal::Animal(std::string Name)
{
name = Name;
}
Dog::Dog(std::string Name) :Animal(Name)
{
}
void Animal::eat()
{
std::cout << name << "基类eat" << std::endl;
}
void Dog::eat()
{
std::cout << name << "子类eat" << std::endl;
}
int main()
{
Animal* dog = new Dog("狗子"); //注意定义是用 Animal 作为 class 类型
dog->eat(); //dog 指针调用 eat()
delete dog;
return 0;
}
output:
狗子基类eat
明明是 Dog 是 Animal 的继承子类,为什么不打印 狗子子类eat
呢?
程序之所以会有这样奇怪的行为,是因为C++的创始者希望用C++生成的代码和C语言一样快,所以程序在编译的时候,编译器将检查所有的代码,在对数据处理和对该类型的数据进行处理之间寻找一个最佳点,正是这一项检查影响了刚才的程序结果,编译器认为 dog
调用的 eat()
是 Animal::eat()
,故打印出基类的 eat()
那解决的方法是什么呢?很简单,声明一个虚方法就好了
声明一个虚方法的语法非常简单,只要在其原型前边加上 virtual 关键字即可,以上一题举例,在基类声明 virtual void eat()
即可
另外,虚方法是继承的,一旦在基类里把某个方法声明为虚方法,在子类里就不可能再把它声明为一个非虚方法了,这对于设计程序来说是一件好事,因为程序员无需顾虑一个虚方法会在某个子类里变成一个非虚方法
TIPS(小提示)
2、抽象方法 之 纯虚函数
根据上一节我们知道了虚函数的定义方法,只需在基类定义:
virtual void eat();
那么现在讲纯虚函数的定义方法,也很简单,只需在基类定义:
virtual void eat() = 0;
没错,加个 = 0 即可,那有什么用呢?纯虚函数告诉编译器不用浪费时间在这个类里寻找这个方法的实现,节省时间和空间(其实还有其他用途,只是暂时学不到)