在类的定义中,前面有virtual关键字的成员函数就是虚函数。多态是通过虚函数来实现的。
Class base{
Virtual int get();
};
Int base::get() { }
- Virtual 关键字只用在类定义里的函数声明中,写函数体时不用。
- 构造函数和静态成员函数不能是虚函数
- 虚函数可以参与多态,而普通成员函数不可以。
多态的变现形式之一
- 派生类的指针可以赋给基类指针
- 通过基类指针调用基类和派生类中的同名虚函数时:
(1)若该指针指向一个基类的对象,那么被调用是基类的虚函数。
(2)若该指针指向一个派生类的对象,那么被调用的是派生类的虚函数。
这种机制就叫做多态。
多态的表现形式二
- 派生类的对象可以赋给基类引用
- 通过基类引用调用基类和派生类中的同名虚函数时:
(1)若该引用引用的是一个基类的对象,那么被调用的是基类的虚函数;
(2)若该引用引用的是一个派生类的对象,那么被调用的是派生类的虚函数。
这种机制也是多态。
多态的作用
在面向对象的程序设计中使用多态,能够增强程序的可扩充性,即程序需要修改或增加功能的时候,需要改动和增加的代码较少。
多态的常用方法
用基类指针数组存放指向各种派生类对象的指针,然后遍历该数组,就能对各个派生类对象做各种操作,是很常用的做法。
在非构造函数,非析构函数的成员函数中调用虚函数是多态。
在构造函数和析构函数中调用虚函数不是多态,编译即可确定,调用的函数是自己的类或基类中定义的函数。
派生类中和基类中虚函数同名同参数表的函数,不加virtual也自动成为虚函数。
测试代码如下:
#include <iostream> #include <string> using namespace std; class A { private: int val; public: A(int val) :val(val) {}; virtual void addVal() { val += 10; cout << "A::addVal() is called" << endl; } void print() { cout << val << " "; cout << "hello world!" << endl; } }; class B :public A { private : string name; int value; public: B(string name, int value, int val) :A(val), name(name), value(value) {}; virtual void addVal() { value += 50; cout << value << " "; cout << "B::addVal() is called" << endl; } void print() { cout << name << endl; } void printHH() { cout << "HH" << endl; } }; int main() { A a(5); B b("chen", 8, 2); b.print(); A & a1=b; a1.addVal(); A *a2; a2 = &b; a2->addVal(); a2->print();//调用的是基类中的print函数。原因是当基类和继承类中的函数名相同时,会优先调用自己类中的成员函数,a2是基类指针,属于基类因此会调用基类的成员函数。b.print()是调用继承类中的成员函数,因为b是继承类。 return 0; }
参考链接:
https://www.coursera.org/learn/cpp-chengxu-sheji