虚函数——多态的关键

一、未使用虚函数的继承

    a)父类与子类定义

class Father
{
public:
Father(){}
~Father(){}

void print(){cout<<"这是父类:Father"<<endl;}
};

class Clild_A:public Father
{
void print(){cout<<"这是子类:Child_A"<<endl;}
};

class Clild_B:public Father
{
void print(){cout<<"这是子类:Child_B"<<endl;}
};


   b)全局函数print()

void print( Father &theFather)
{
theFather.print();
}


   c)主函数

int _tmain(int argc, _TCHAR* argv[])
{

Father *theFather_A=new Clild_A();
Father *theFather_B=new Clild_B();

print(*theFather_A);
print(*theFather_B);

delete theFather_A;
delete theFather_B;

system("pause");
return 0;
}

运行结果:



二、使用了虚函数的继承——多态

     a)父类与子类定义

class Father
{
public:
Father(){}
virtual ~Father(){}//保证父类指针指向子类时,delete基类指针,子类的析构行为能正确调用

virtual void print(){cout<<"这是父类:Father"<<endl;}
};

class Clild_A:public Father
{
virtual void print(){cout<<"这是子类:Child_A"<<endl;}
};

class Clild_B:public Father
{
virtual void print(){cout<<"这是子类:Child_B"<<endl;}
};

   b)全局函数print()

void print( Father &theFather)
{
theFather.print();
}


   c)主函数

int _tmain(int argc, _TCHAR* argv[])
{

Father *theFather_A=new Clild_A();
Father *theFather_B=new Clild_B();

print(*theFather_A);
print(*theFather_B);

delete theFather_A;
delete theFather_B;

system("pause");
return 0;
}

 运行结果:

  注:a)Virtual 用来告诉系统,遇到这个处理过程要等到执行时再确定到底调用哪个类的处理过程

      b)多态的两大核心:1)虚函数

                                 2)父类引用指向子类(使得在添加新类时,print方法无需修改

三、面向过程实现等价功能的繁琐处理

        需要在全局print函数中,用switch区分出传递进来的分别是哪个子类,然后调用各个子类

  相应print方法;

        而且以后每增加一个子类,就要修改全局print函数



附: 虚函数与纯虚函数对比

(1)纯虚函数只有定义,没有实现;而虚函数既有定义,也有实现的代码。
(2)包含纯虚函数的类不能定义其对象,而包含虚函数的则可以。
原文地址:https://www.cnblogs.com/edisonfeng/p/2215974.html