请选择 进入手机版 | 继续访问电脑版

环信

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: mmap uikit gcc
查看: 204|回复: 0

C++多态

[复制链接]

21

主题

43

帖子

140

积分

注册会员

Rank: 2

积分
140
发表于 2016-1-25 11:19:34 | 显示全部楼层 |阅读模式
  1. /*
  2. * 多态:
  3. * 1. 继承关系
  4. * 2. 函数覆盖(重写)
  5. * 3. 虚函数
  6. * 4. 用父类的指针或者引用访问对象自己,不能是另一个对象
  7. * 5. 在父类中,需要加入虚析构函数
  8. *
  9. */
  10. class Parent
  11. {
  12. public:
  13.     void print()
  14.     {
  15.         cout<<"I'm Parent..."<<endl;
  16.     }
  17. };

  18. class Child : public Parent
  19. {
  20. public:
  21.     void print()
  22.     {
  23.         cout<<"I'm Child..."<<endl;
  24.     }
  25. };

  26. void run()
  27. {
  28.     Child child;
  29.     Parent* pp = &child;
  30.     Parent& rp = child;

  31.     child.print();
  32.     pp->print();
  33.     rp.print();
  34. }

  35. int main()
  36. {
  37.     run();
  38.     return 0;
  39. }
复制代码

在编译时,编译器自动根据指针的类型判断指向的是一个什么样的对象
所以编译器认为父类指针指向的是父类对象(根据赋值兼容性原则,这个假设合理)
由于程序没有运行,所以不可能知道父类指针指向的具体是父类对象还是子类对象
从程序安全的角度,编译器假设父类指针只指向父类对象,因此编译的结果为调用父类的成员函数

C++中通过virtual关键字对多态进行支持
使用virtual声明的函数被重写后即可展现多态特性
根据实际对象的类型确定调用的具体函数

函数重载
    必须在同一个类中进行
    子类无法重载父类的函数,父类同名函数将被覆盖
    重载是在编译期间根据参数类型和个数决定调用函数
函数重写
    必须发生于父类与子类之间
    并且父类与子类中的函数必须有完全相同的原型
    使用virtual声明之后能够产生多态
    多态是在运行期间根据具体对象的类型决定调用函数


虚函数的实现原理
当类中声明虚函数时,编译器会在类中生成一个虚函数表
虚函数表是一个存储类成员函数指针的数据结构
虚函数表是由编译器自动生成与维护的
virtual成员函数会被编译器放入虚函数表中
存在虚函数时,每个对象中都有一个指向虚函数表的指针
virtual1.jpg

virtual2.jpg

virtual3.jpg

对象在创建的时候由编译器对VPTR指针进行初始化
只有当对象的构造完全结束后VPTR的指向才最终确定
父类对象的VPTR指向父类虚函数表
子类对象的VPTR指向子类虚函数表
构造函数中调用虚函数无法实现多态。


抽象类
    是一种只能定义类型,而不能产生对象的类,只能被继承并重写相关函数
    直接特征是纯虚函数。
纯虚函数是只声明函数原型,而故意不定义函数体的虚函数。


函数重载与函数重写不同
多态是通过虚函数表实现的
虚函数在效率上会受到影响
抽象类可用于表示现实世界中的抽象概念
抽象类是通过纯虚函数实现的
  1. class Shape
  2. {
  3. public:
  4.     virtual double area() = 0;
  5. };

  6. class Rectangle : public Shape
  7. {
  8.     double m_a;
  9.     double m_b;
  10. public:
  11.     Rectangle(double a, double b)
  12.     {
  13.         m_a = a;
  14.         m_b = b;
  15.     }
  16.    
  17.     double area()
  18.     {
  19.         return m_a * m_b;
  20.     }
  21. };

  22. class Circle : public Shape
  23. {
  24.     double m_r;
  25. public:
  26.     Circle(double r)
  27.     {
  28.         m_r = r;
  29.     }
  30.    
  31.     double area()
  32.     {
  33.         return 3.14 * m_r * m_r;
  34.     }
  35. };

  36. void area(Shape* s)
  37. {
  38.     cout<<s->area()<<endl;
  39. }

  40. int main(int argc, char *argv[])
  41. {
  42.     Rectangle rect(2, 3);
  43.     Circle circle(4);
  44.    
  45.     area(&rect);
  46.     area(&circle);
  47.     return 0;
  48. }
复制代码



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|环信 Glofty.com ( 粤ICP备15084637号 )

GMT+8, 2017-1-23 16:34 , Processed in 0.224874 second(s), 25 queries .

快速回复 返回顶部 返回列表