C++第08课 虚函数和多态 (一)
1.虚函数
+ 在类中用virtual 修饰的函数 叫做虚函数
+ 没有虚构造函数,但是存在虚析构函数
虚函数对于类的类内存影响
+ 没有数据成员类是占用1个字节,普通函数对于类的内存是毫无影响
+ 所有虚函数都是用一个指针存储:虚函数指针
+ 通过虚函数表的理解去访问虚函数
class MM { public: virtual void print1() { cout << "print1" << endl; } virtual void print2() { cout << "print2" << endl; } }; int main() { //通过虚函数表访问虚函数 MM mm; int** p = (int**)&mm; void (*pfun1)() = (void(*)())p[0][0]; //print1 pfun1(); void (*pfun2)() = (void(*)())p[0][1]; //print2 pfun2(); typedef void(*pFun)(); void (*pfun11)() = (pFun)((int**)(&mm))[0][0]; //print1 pfun11(); void (*pfun22)() = (pFun)((int**)(&mm))[0][1]; //print2 pfun22(); return 0; }
2.纯虚函数和抽象类
+ 纯虚函数是一种特殊的虚函数,纯虚函数是没有函数体的,注意写法
+ 具有至少一个纯虚函数的类叫做抽象类
+ 抽象类不能构建对象
+ 抽象类可以构建对象指针
+ 抽象类产生一个子类,子类想要构建对象,必须要重写父类中的纯虚函数
class MM { public: //纯虚函数 virtual void print() = 0; }; //只有在子类重写了父类的纯虚函数才能构建对象 class Girl :public MM{ public: void print() { cout << "Hello World!" << endl; } }; int main() { //不能构建对象 MM* mm = nullptr; Girl g; g.print(); return 0; }
3.多态实现
+ 数据类型上多态:基类指针可以被父类和子类对象初始化
+ 函数调用上的多态:相同的函数调用导致的不同的行为(结果)
多态的必要条件:
+ 必须存在虚函数,子类中必须存在一样的函数
+ 必须存在不正常指针引用关系(指针赋值)
+ 必须是public继承
class MM { public: virtual void print() { cout << "MM print" << endl; } void printMM() { cout << "print MM" << endl; } }; class Girl :public MM{ public: void print() { cout << "Girl print" << endl; } void printMM() { cout << "print Girl" << endl; } }; int main() { //正常的赋值关系 //MM mm; //mm.print(); //MM print //MM& mm1 = mm; //mm1.print(); //MM print //MM* mm2 = new MM; //mm2->print(); //MM print //Girl gg; //gg.print(); //Girl print //Girl& gg1 = gg; //gg1.print(); //Girl print //Girl* gg2 = new Girl; //gg2->print(); //Girl print //不正常的赋值关系 MM* p = new Girl; //父类指针用子类对象初始化,即子到父,称为上行转换 p->print(); //Girl print 如果没有virtual调用的就是父类的 p->printMM(); //print MM Girl g; MM& p1 = g; p1.print(); //Girl print p1.printMM(); //print MM Girl* pp = static_cast<Girl*>(new MM); //子类指针用父类对象初始化,即父到子,称为下行转换 pp->print(); //MM print pp->printMM(); //print Girl MM mm; Girl& pp2 = static_cast<Girl&>(mm); pp2.print(); //MM print pp2.printMM(); //print Girl return 0; }