云顶娱乐手机官网-云顶娱乐网址

热门关键词: 云顶娱乐手机官网,云顶娱乐网址

C++多态的实现机制

2019-09-23 作者:编辑程序   |   浏览(138)

  在上一篇C++ 学习笔记 承接- 子类与父类有同名函数,变量中说了当父类子类有同名函数时在外表调用时一旦不加父类名则会私下认可调用子类的函数。C++有函数重写的功力须要增加virtual关键字,当时写上篇博文的时候在想那么既然私下认可使用子类的同名函数那么这么些virtual有怎样含义吗?

1.用类定义对象的时候,假若类中蕴涵有虚函数的话,C++编译器为种种对象编了一个一维的虚函数表(简称虚表)。那个虚函数表存款和储蓄了类中虚函数的函数入口地址;

这篇博文首要汇报 多态:一句同样的语句能有两样的落到实处。

2.用类定义对象的时候,要是类中蕴藏有虚函数的话,C++编译器还为每种对象分配了贰个针对虚表起先地址的指针vptr;

  

3.现代码运维时,C++编写翻译器首先剖断父类指针调用的函数是还是不是虚函数。

C++多态的实现机制。  当父类和子类有同名函数,调用时拉扯到了指针那么就跟virtual有提到了。

假诺不是虚函数,则是一般函数。即使函数实参传的是父类对象的地方(或父类对象的引用),则父类指针调用父类对象中的普通函数;假如实参传的是子类对象的地点(或子类对象的引用),则父类指针调用子类中承继自父类的家常函数。

  看之下两种情况:

一旦是虚函数,则利用传递过来的实参的vptr指针找到虚表,依照虚表找到虚函数的输入地址,实施函数代码。那些进程C++编写翻译器不需决断传来的实参是父类对象的地点(或援引)依然子类对象的地点(或引用),而是直接用传递过来的实参对象的vptr指针。

  定义七个类:父类子类有同名函数print();

 

 1 class Parent 2 { 3 public: 4  5     void print() //子类的和父类的函数名字一样 6     { 7         cout<<"Parent 打印 "<<endl; 8     } 9 10 };11 12 class Child : public Parent13 {14 public:15 16     void print()  17     {18         cout<<"Child 打印  "<<endl;19     }20 21 };

以如下的代码为例:

  

 1 #include<iostream>
 2 using namespace std;
 3 
 4 class Parent
 5 {
 6 public:
 7     Parent(int _a):a(_a){}
 8     ~Parent(){cout<<"执行Parent类析构函数"<<endl;}
 9     virtual void print(){cout<<"打印Parent类 a:"<<a<<endl;}
10 
11 public:
12     int a;
13 };
14 
15 
16 class Child:public Parent
17 {
18 public:
19     Child(int _a,int _a_,int _b):Parent(_a),a(_a_),b(_b){}
20     ~Child(){cout<<"执行Child类析构函数"<<endl;}
21     void print(){cout<<"打印Child类 b:"<<b<<endl;}
22 
23 public:
24     int a;
25     int b;
26 };
27 
28 
29 void fun(Parent* p)
30 {
31     p->print();
32 }
33 
34 
35 
36 int main()
37 {
38     Parent p(5);
39     Child  c(20,30,40);
40 
41     fun(&p);
42     fun(&c);
43     
44     return 0;
45 }

1.当父类和子类皆有同名函数prin()t时,使用Parent 类指针,指向子类对象或许父类对象调用的函数都以父类的函数。

代码的实施结果为:

   Parent    *base = NULL;

 5     base = &p1;    //父类对象 6     base->print(); //执行父类的打印函数 7  8     base = &c1;    //子类对象 9     base->print(); //也是执行父类函数

打印Parent类 a:5

  

打印Child类 b:40

2.采用援用,当引用是父类时调用的函数也是父类的同名函数

实践Child类析构函数

Parent &base2 = p1;         base2.print();//调用父类函数        Parent &base3 = c1; //base3是c1 的别名        base3.print(); //调用父类函数

实行Parent类析构函数

 

实践Parent类析构函数

3.函数字传送参为父类 类型时,无论传入子类依然父类都只举行父类的函数

 

voidhowToPrint(Parent *base)//传参为父类的指针 
{     base->print(); } 

 void howToPrint2(Parent &base)  //传参为父类的引用 {     base.print(); }          //函数调用 均执行父类的函数     howToPrint(&p1);     howToPrint(&c1);     howToPrint2
     howToPrint2;        

分析:

总结:

1.代码中的fun()函数调用的print()函数是虚函数,则走的是vptr-->虚表-->虚函数代码那条路线

  其实下边八个场景下当大家八个指针指向了子类,或许引用子类那么我们盼望调用函数的时候是调用子类的函数,可是其实情状却不是那样。那时候就要求virtual关键字了。

2.起先化子类Child的目的c时,c.vptr的伊始化是布满进行的:当实践父类的构造函数时,c.vptr指向父类的虚函数表,当父类的构造函数实施完结后,会把c.vptr指向子类的虚函数表。

 1 lass Parent 2 { 3 public: 4  5     virtual void print() //子类的和父类的函数名字一样 6     { 7         cout<<"Paren打印 "<<endl; 8     } 9 10 };11 12 class Child : public Parent13 {14 public:15 16     virtual void print() //virtual 父类写了virtual,子类可写 可不写 17     {18         cout<<"Child 打印  "<<endl;19     }20 21 };

 

  使用了virtual关键字定义的函数,那么在上述三种情况下纵然指针是指向子类,或是引用子类那么将来的调用就依据大家的意料调用子类里的函数。再纪念一下那句话:

对多态的知道:

  多态:一句一样的讲话能有不相同的贯彻。

多态的兑现效果与利益:一样的调用语句有多样不相同的变现形态;

举例:
voidhowToPrint(Parent *base)//传参为父类的指针 
{     base->print(); } 传入的指针决定了最后执行的函数,出入父类指针则执行父类的print函数,出入父类的派生类则调用这个派生类的print函数,这样一句相同的语句就有了不同的实现。

多态达成的3个原则:a.要有再三再四  b.有virtual重写  c.有父类指针(引用)指向子类对象;

voidhowToPrint(Parent *base)//传参为父类的指针

多态的C++完成:virtual关键字,告诉编写翻译器这些函数要支持多态,不是依据指针类型决定函数调用,而是要依附指针所针对的骨子里指标类型来调整函数调用;

多态的说理基础:静态联编PK动态联编,依据实际指标的体系来决断重写函数的调用;

多态的主要意义:设计形式的基础,框架的内核;

贯彻多态的理论基础:函数指针做函数参数;

多态的兑现原理:C++编写翻译器提前布局了贰个vptr指针,利用vptr指针找到虚函数表,进而找到函数的输入地址,进行动态的迟绑定

 

本文由云顶娱乐手机官网发布于编辑程序,转载请注明出处:C++多态的实现机制

关键词:

  • 上一篇:没有了
  • 下一篇:没有了