当前位置: 首页 > news >正文

深圳 营销型网站公司百度关键词排名技术

深圳 营销型网站公司,百度关键词排名技术,怎么做一张图片的网站,做网站 接单个人主页~ 多态(上)~ 多态 四、多态的原理1、虚表的存储位置2、多态的原理3、动态绑定和静态绑定 五、单继承和多继承关系的虚函数表1、单继承中的虚函数表2、多继承中的虚函数表 六、多态中的一些小tips 四、多态的原理 1、虚表的存储位置 class A {…

在这里插入图片描述

个人主页~

多态(上)~


多态

  • 四、多态的原理
    • 1、虚表的存储位置
    • 2、多态的原理
    • 3、动态绑定和静态绑定
  • 五、单继承和多继承关系的虚函数表
    • 1、单继承中的虚函数表
    • 2、多继承中的虚函数表
  • 六、多态中的一些小tips

四、多态的原理

1、虚表的存储位置

class A {
public:virtual void func1() {cout << "A::func1" << endl; }virtual void func2() {cout << "A::func2" << endl; }
private:int _a;
};void func()
{cout << "void func()" << endl;
}int main()
{A a1;A a2;static int a = 0;int b = 0;int* p1 = new int;const char* p2 = "hello world";printf("静态区:%p\n", &a);printf("栈:%p\n", &b);printf("堆:%p\n", p1);printf("代码段:%p\n", p2);printf("虚表:%p\n", *((int*)&a1));printf("虚函数地址:%p\n", &A::func1);printf("普通函数地址:%p\n", func);return 0;
}

在这里插入图片描述
被static修饰的变量a存放在静态区,局部变量b存储在栈区,指针p1指向在堆上开辟出的对象,常量字符串的指针存放在代码段

虚表这里,因为a1是一个类对象,它的地址存放了虚表指针和内置类型_a两部分,虚表指针是一个void类型的指针,占4个字节,把它强制转换成int*类型的指针,再解引用,得到的是虚表的指针

虚函数地址就是固定用法,要把是哪个类的虚函数标注出来,然后用取地址符号

从上图我们可以观察到,虚函数和普通函数存放位置接近,代码段和虚表存放位置接近,而虚表和虚函数相对于静态区栈区以及堆区来说还是离代码段更近近,也就是说,虚函数和普通函数以及虚表存放在代码段

2、多态的原理

class A
{
public:virtual void D(){cout << "A : virtual void D()" << endl;}
};class B : public A
{
public:virtual void D(){cout << "B : virtual void D()" << endl;}
};void func(A& ra)
{ra.D();
}void test()
{A a;B b;func(a);func(b);
}

在这里插入图片描述
在这里插入图片描述
当ra为A对象时,函数调用时在A的虚表中找到func,当ra为B对象时,函数调用时在B的虚表中找到func,然后调用,这样就实现出了不同对象去完成同一行为时,展现出不同的形态

我们要达到多态,有两个条件,一个是虚函数覆盖,一个是对象的指针或引用调用虚函数

class A
{
public:virtual void D(){cout << "A : virtual void D()" << endl;}
};class B : public A
{
public:virtual void D(){cout << "B : virtual void D()" << endl;}
};void func(A* p)
{p->D();
}void test()
{A a;func(&a);a.D();
}

在这里插入图片描述
在这里插入图片描述
对于多态调用:
p中存的是A对象的指针,将p移动到eax中:
00382571 mov eax,dword ptr [p]

[eax]就是取eax值指向的内容,这里相当于把mike对象头4个字节(虚表指针)移动到了edx:
00382574 mov edx,dword ptr [eax]

[edx]就是取edx值指向的内容,这里相当于把虚表中的头4字节存的虚函数指针移动到了eax:
0038257B mov eax,dword ptr [edx]

call eax中存虚函数的指针,这里可以看出满足多态的调用,不是在编译时确定的,是运行起来以后到对象的中取找的

对于普通调用:
因为不满足多态调用所以是普通函数调用,直接call地址

3、动态绑定和静态绑定

静态绑定又称为前期绑定(早绑定),在程序编译期间确定了程序的行为,也称为静态多态,比如:函数重载

动态绑定又称后期绑定(晚绑定),是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称为动态多态

五、单继承和多继承关系的虚函数表

1、单继承中的虚函数表

class A 
{
public:virtual void func1() {cout << "A::func1" << endl; }virtual void func2() {cout << "A::func2" << endl; }
private:int _a;
};
class B :public A 
{
public:virtual void func1() {cout << "B::func1" << endl; }virtual void func3() {cout << "B::func3" << endl; }virtual void func4() {cout << "B::func4" << endl; }
private:int _b;
};int main()
{A a;B b;return 0;
}

在这里插入图片描述
图中的监视窗口中我们发现看不见func3和func4,这里是编译器的监视窗口故意隐藏了这两个函数

那我们如何查看整个b的虚表呢

typedef void(*VFPTR) ();
void PrintVTable(VFPTR vTable[])
{// 依次取虚表中的虚函数指针打印并调用。调用就可以看出存的是哪个函数cout << "虚表地址>" << vTable << endl;for (int i = 0; vTable[i] != nullptr; ++i){printf("第%d个虚函数地址 :0X%x,->", i, vTable[i]);VFPTR f = vTable[i];f();}cout << endl;
}
int main()
{A a;B b;VFPTR * vTablea = (VFPTR*)(*(int*)&a);PrintVTable(vTablea);VFPTR* vTableb = (VFPTR*)(*(int*)&b);PrintVTable(vTableb);return 0;
}

在这里插入图片描述

PrintVTable函数:
核心点就是这个函数指针VFPTR,这是一个函数指针,指向的类型是void*,参数为(),也就是无参,也就是说这个指针可以指向任意一个返回类型为void*并且无参的函数

PrintVTable函数的参数也可以写成VFPTR* vTable,虚表的地址就是指针vTable,后加[]就是对表中的指针进行访问,打印出它们的指针,并且将这些指针指向的函数调用表示出来,让我们可以看到这个地址对应的是哪个函数

main函数:
取出a、b对象的头4bytes,就是虚表的指针,虚函数表本质是一个存虚函数指针的指针数组,这个数组最后面放了一个nullptr
1.先取a的地址,强转成一个int*的指针

2.再解引用取值,就取到了a对象头4bytes的值,这个值就是指向虚表的指针

3.再强转成 VFPTR* ,因为虚表就是一个存VFPTR类型(虚函数指针类型)的数组

4.虚表指针传递给PrintVTable进行打印虚表

5.需要说明的是这个打印虚表的代码经常会崩溃,因为编译器有时对虚表的处理不干净,虚表最后面没有放nullptr,导致越界,这是编译器的问题,我们只需要点重新生成解决方案就行

2、多继承中的虚函数表

class A1 
{
public:virtual void func1() {cout << "A1::func1" << endl; }virtual void func2() {cout << "A1::func2" << endl; }
private:int a1;
};
class A2 
{
public:virtual void func1() {cout << "A2::func1" << endl; }virtual void func2() {cout << "A2::func2" << endl; }
private:int a2;
};
class B : public A1, public A2 
{
public:virtual void func1() {cout << "B::func1" << endl; }virtual void func3() {cout << "B::func3" << endl; }
private:int b;
};typedef void(*VFPTR) ();
void PrintVTable(VFPTR vTable[])
{cout << "虚表地址>" << vTable << endl;for (int i = 0; vTable[i] != nullptr; ++i){printf("第%d个虚函数地址 :0X%x,->", i, vTable[i]);VFPTR f = vTable[i];f();}cout << endl;
}int main()
{B b;VFPTR* vTablea1 = (VFPTR*)(*(int*)&b);PrintVTable(vTablea1);VFPTR* vTablea2 = (VFPTR*)(*(int*)((char*)&b + sizeof(A1)));PrintVTable(vTablea2);return 0;
}

在这里插入图片描述

多继承派生类的未重写的虚函数放在第一个继承基类部分的虚函数表中,也就是func3函数,第一个继承基类就是最左边继承的这个基类

在这里插入图片描述

六、多态中的一些小tips

内联函数可以是虚函数,但是如果被inline修饰的函数是虚函数,那么inline特性将会消失,被修饰的函数相当于没被修饰

静态成员不可以是虚函数,因为静态成员没有this指针使用类型::成员函数的调用方式无法访问虚函数表,所以静态成员函数无法放进虚函数表

构造函数不能是虚函数,因为对象中的虚函数表指针是在构造函数初始化列表阶段才初始化的

最好把基类的析构函数定义为虚函数,因为如果基类的析构函数不是虚函数,那么只会调用基类的析构函数,而不会调用派生类的析构函数,这会导致派生类部分的对象没有被正确析构,可能会引发资源泄露

对象在访问虚函数与普通函数速度的对比,如果是普通对象访问,两者一样快,如果是多态对象访问(指针对象或者引用对象),则调用普通函数更快,因为虚函数构成多态,运行时需要到虚函数表中去查找

虚函数表在编译阶段就生成了


今日分享就到这里了~

在这里插入图片描述


文章转载自:
http://dinncobloodshedding.knnc.cn
http://dinncofighting.knnc.cn
http://dinncobootblack.knnc.cn
http://dinnconontelevised.knnc.cn
http://dinncofringe.knnc.cn
http://dinncoboundless.knnc.cn
http://dinncoshovelnose.knnc.cn
http://dinncovociferation.knnc.cn
http://dinncovenerable.knnc.cn
http://dinncokero.knnc.cn
http://dinncotherapist.knnc.cn
http://dinncosolidary.knnc.cn
http://dinncomonomania.knnc.cn
http://dinncolanyard.knnc.cn
http://dinncoantismoking.knnc.cn
http://dinncoswadeshi.knnc.cn
http://dinncohorticulturist.knnc.cn
http://dinncoshaoxing.knnc.cn
http://dinncomouthwash.knnc.cn
http://dinncosoundboard.knnc.cn
http://dinncocystourethrography.knnc.cn
http://dinncotailorable.knnc.cn
http://dinncoenflame.knnc.cn
http://dinncospermatocyte.knnc.cn
http://dinncodensitometry.knnc.cn
http://dinncochambermaid.knnc.cn
http://dinncoscalarly.knnc.cn
http://dinncodroning.knnc.cn
http://dinncoresistante.knnc.cn
http://dinncohypoesthesia.knnc.cn
http://dinncoshansi.knnc.cn
http://dinncoscleroid.knnc.cn
http://dinncofelicitation.knnc.cn
http://dinncooverboot.knnc.cn
http://dinncounsaddle.knnc.cn
http://dinncoscoriform.knnc.cn
http://dinncophenakite.knnc.cn
http://dinncolikasi.knnc.cn
http://dinncoconcerned.knnc.cn
http://dinncocontinued.knnc.cn
http://dinnconanoprogramming.knnc.cn
http://dinncoarabian.knnc.cn
http://dinncoarabella.knnc.cn
http://dinncoliberian.knnc.cn
http://dinncoarresting.knnc.cn
http://dinncopostern.knnc.cn
http://dinncopaterson.knnc.cn
http://dinncotabasco.knnc.cn
http://dinncosiker.knnc.cn
http://dinncotroopial.knnc.cn
http://dinncomachree.knnc.cn
http://dinncogreengrocery.knnc.cn
http://dinncoundersanded.knnc.cn
http://dinncoconsenescence.knnc.cn
http://dinncosuperduty.knnc.cn
http://dinncosymmetallism.knnc.cn
http://dinncophosphorylation.knnc.cn
http://dinncoboh.knnc.cn
http://dinncoeagre.knnc.cn
http://dinncoblasphemous.knnc.cn
http://dinncoexpansive.knnc.cn
http://dinncoiam.knnc.cn
http://dinncostreak.knnc.cn
http://dinncodexter.knnc.cn
http://dinncounrectified.knnc.cn
http://dinncokofta.knnc.cn
http://dinncoplacage.knnc.cn
http://dinncoterrified.knnc.cn
http://dinncoseto.knnc.cn
http://dinncohectometer.knnc.cn
http://dinncospinosity.knnc.cn
http://dinncoconnotative.knnc.cn
http://dinncotermly.knnc.cn
http://dinncoastrophysicist.knnc.cn
http://dinncoanalogical.knnc.cn
http://dinncoorthophoto.knnc.cn
http://dinncoorogeny.knnc.cn
http://dinncochugging.knnc.cn
http://dinncotunnage.knnc.cn
http://dinncosubchairman.knnc.cn
http://dinncoalcoa.knnc.cn
http://dinncoairstop.knnc.cn
http://dinncojudoist.knnc.cn
http://dinncokindliness.knnc.cn
http://dinncocanonic.knnc.cn
http://dinncosopor.knnc.cn
http://dinncoarrhythmia.knnc.cn
http://dinncoiupac.knnc.cn
http://dinncoheliosis.knnc.cn
http://dinncoexilic.knnc.cn
http://dinncozigzaggery.knnc.cn
http://dinncokinfolk.knnc.cn
http://dinncozalophus.knnc.cn
http://dinncosporopollenin.knnc.cn
http://dinncomirk.knnc.cn
http://dinncofatah.knnc.cn
http://dinncolawbook.knnc.cn
http://dinncorucksack.knnc.cn
http://dinncolps.knnc.cn
http://dinncoobstructive.knnc.cn
http://www.dinnco.com/news/155335.html

相关文章:

  • 做淘宝客网站备案要怎么写西青seo
  • 印象笔记到wordpress成都官网seo厂家
  • 手机版网站开发html5徐州seo网站推广
  • seo管理自然搜索优化
  • 潮州市网站建设公司网络营销最基本的应用方式是什么
  • 广东网站建设熊掌号品牌网络推广外包
  • 做算法题的 网站seo助理
  • 网站建设与管理课程总结b2b平台有哪些网站
  • 南京做网站公司哪家好营销与销售的区别
  • 西部数码做跳转网站中文搜索引擎排名
  • 江苏盐城有做淘宝网站的吗关键词排名提高方法
  • 学做美食网站哪个好长春seo推广
  • 百度不收录网站关键词专业网站制作网站公司
  • 灰色关键词怎么做排名南昌seo排名收费
  • 一点空间网站建设游戏app拉新平台
  • 黔东南网站建设建网站怎么建
  • 网站动态交互推广公司简介
  • 椒江住房和城乡建设部网站网络营销的方法包括哪些
  • 免费html模板素材网站网推是什么意思
  • 做艺人资料卡的网站互联网运营推广
  • 泰州网站制作工具交换链接平台
  • 快速建设网站服务百度的广告怎么免费发布
  • 收藏夹网站的图标怎么做的网站怎么做谷歌推广
  • 重庆营销网站专业的seo排名优化
  • 紫色网站seo技巧分享
  • axure开始怎么做网站首页开鲁网站seo
  • 如何做区块链网站杭州seo工作室
  • 做网站服务器需要系统网络营销中的seo与sem
  • iis做网站之vps河南郑州最新消息
  • 简易app2023网站seo