C++多态的深入浅出

概念:

       当父类型的指针或者引用指向子类对象时,通过父类型的指针调用虚函数,如果子类重写了这个虚函数,则调用的表现是子类的,否则就是父类型的。

       注意:如果调用的是名字隐藏的函数,则调用的是父类的函数,而不是子类的函数。因为指针类型是父类型的

       继承是构成多态的基础。

       虚函数是构成多态的关键。

       函数重写是必备条件

     

       举个通俗易懂的例子:

#include <iostream>
using namespace std;
class Animal{
	public:
		void show(){
			cout << "animal show()" << endl;
		}
		virtual void run(){
			cout << "animal run()" << endl;
		}
		virtual void fun(){
			cout << "animal fun()" << endl;
		}
};

class Cat:public Animal{
	public:
		void show(){
			cout << "cat show()" << endl;
		}
		virtual void run() {                  //是否带virtual关键字都重写了父类的虚函数 
			cout << "cat run()" << endl;
		}
		void fun(){                           //是否带virtual关键字都重写了父类的虚函数 
			cout << "cat fun()" << endl;
		}
};

class Fish:public Animal{
	public:
		void run(){
			cout << "fish run()" << endl;
		}
		void fun(){
			cout << "fish fun()" << endl;
		}

};

int main(){
	cout << "子类对象调用子类函数" << endl;
	Cat cat;
	cat.show();
	cat.run();
	cat.fun();
	
	cout << "子父类对象调用父类函数" << endl;
	Animal animal;
	animal.show();
	animal.run();
	animal.fun();
	
	cout << "父类型指针指向子类对象,用到多态,需要注意子类对父类的虚函数重写" << endl;
	Animal *pa = &cat;
	pa->show();    //animal
	pa->run();   //cat
	pa->fun();   //cat
	
	cout << "拷贝构造函数,注意不涉及多态,直接调用父类函数" << endl;
	Fish fish;
	Animal af = fish;   //调用animal的拷贝构造函数,本质是定义初始化一个af对象
	af.show();   //animal
	af.run();   //animal
	af.fun();   //animal
	
	cout << "父类型引用指向子类对象,用到多态,需要注意子类对父类的虚函数重写" << endl;
	Animal& an = fish;
	an.show();   //animal
	an.run();   //fish
	an.fun();   //fish

}

   运行结果:    

               

        Animal是父类,其含有run()和fun()两个虚函数, 另一个是普通的成员函数show()。 子类Cat和Fish都继承了父类Animal并都重写了run()和fun()函数。所以当Animal类型的指针或者引用指向子类对象的时候,调用run()和fun()函数,最终表现为调用子类重写的run()和fun()函数。

        因为show()函数在父类中只是普通的成员函数,那么子类中的show()函数不构成对父类show()的重写。因此,父类型的指针调用show()还是调用父类的show()。

 

应用:

      既想调cat的run(),又想调用fish的run(),那么一般只能分别调用两次(cat.run(); fish.run())。 如果有多个子类都要调用run(),那么上述调用方法就显得有些累赘。 因此有一个较好的方法,就是实现一个函数,参数是父类型的引用, 在函数体中使用父类型的引用调用父类型的虚函数。  然后调用该函数时,传入子类对象, 就可以通过多态来实现一个函数灵活调用多个子类重写父类的函数。

   举例: 在上述代码的基础上:

void run(Animal& animal) {
	animal.run();
} 

  main函数调用:

run(cat);
run(fish);

   结果:

   

    

猜你喜欢

转载自blog.csdn.net/qq_17152131/article/details/106677584