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

和拓者设计吧类似的网站网络流量分析工具

和拓者设计吧类似的网站,网络流量分析工具,城阳网站建设公司电话,wordpress 交叉导航1.final关键字 引出:设计一个不能被继承的类。有如下方法: class A { private:A(int a0):_a(a){} public:static A CreateOBj(int a0){return A(a);} protected:int _a; } //简介限制,子类构成函数无法调用父类构造函数初始化 //子类的构造…

1.final关键字

引出:设计一个不能被继承的类。有如下方法:

class A
{
private:A(int a=0):_a(a){}
public:static A CreateOBj(int a=0){return A(a);}
protected:int _a;
}
//简介限制,子类构成函数无法调用父类构造函数初始化
//子类的构造函数一定去调用父类的构造函数去初始化那一部分
//而父类的构造函数继承下来后为不可见
class B:public A
{}
int main()
{A aa=;//构造函数被私有化,报错//可以通过如下方法进行A类对象的创建A aa=A::CreateOBj(10);
}

以上的方法虽然可以实现我们的需求,但是会对类进行强制性的封装,所有我们在C++11中还有更好的方法,通过final关键字来实现。

  1. C++11中final声明表示为最终类,表明该类不能被继承。
  2. 修饰函数,限制函数不能被重写。
//修饰类
class A final
{
protected:int _a;
};
//直接限制报错,A不可被继承
class B:public A
{};
//修饰函数
class C
{
public:virtual void f() final{cout<<"C::f()"<<endl;}
}
class D:public C
{
public://直接报错virtual void f(){}
}

2. override

override: 检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错。

class Car{
public:virtual void Drive(){}};class Benz :public Car {public:virtual void Drive() override {cout << "Benz-舒适" << endl;}};

3. 重载、覆盖(重写)、隐藏(重定义)的对比

  • 重载:
    1、两个函数在同一作用域
    2、函数名/参数相同
  • 重写(覆盖):
    1、两个函数分别在基类和派生类的作用域
    2、函数名/参数/返回值都必须相同(协变例外)
    3、两个函数必须是虚函数
  • 重定义(隐藏):
    1、两个函数分别在基类和派生类的作用域
    2、函数名相同
    3、两个基类和派生类的同名函数不构成重写就是重定义

4.纯虚函数

在虚函数的后面写上 =0 ,则这个函数为纯虚函数。

class Student
{
public:virtual void show()=0;
};

5.抽象类

5.1概念

包含纯虚函数的类叫做抽象类(也叫接口类),抽象类不能实例化出对象。派生类继承后也不能实例化出对象,只有重写纯虚函数,派生类才能实例化出对象。纯虚函数规范了派生类必须重写,另外纯虚函数更体现出了接口继承:本质上强制子类去完成虚函数的重写。

 class Car{public:virtual void Drive() = 0;};class Benz :public Car{public:virtual void Drive(){cout << "Benz-舒适" << endl;}};class BMW :public Car{public:virtual void Drive(){cout << "BMW-操控" << endl;}};

5.2接口继承和实现继承

普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实现。虚函数的继承是一种接口继承,派生类继承的是基类虚函数的接口,目的是为了重写,达成多态,继承的是接口。所以如果不实现多态,不要把函数定义成虚函数。

6.多态的原理

6.1认识虚函数表

先来看一道经典的问题,sizeof(Base)是多少?

class Base{public:virtual void Func1(){cout << "Func1()" << endl;}private:int _b = 1;};

很多一部分的答案是4Byte,但实际正确答案是8Byte,这是怎么一回事呢?看Visual Studion下的监视窗口。如下图。
图1
结论:
1.除了_b成员,还多一个__vfptr放在对象的前面(注意有些平台可能会放到对象的最后面,这个跟平台有关),对象中的这个指针我们叫做虚函数表指针(v代表virtual,f代表function)。
2.一个含有虚函数的类中都至少都有一个虚函数表指针,因为虚函数的地址要被放到虚函数表中,虚函数表也简称虚表。
继续深入:如果一个类的继承了该类,那么派生类中这个表放了些什么呢?

// 针对上面的代码我们做出以下改造
// 1.我们增加一个派生类Derive去继承Base
// 2.Derive中重写Func1
// 3.Base再增加一个虚函数Func2和一个普通函数Func3class Base{public:virtual void Func1(){cout << "Base::Func1()" << endl;}virtual void Func2(){cout << "Base::Func2()" << endl;}void Func3(){cout << "Base::Func3()" << endl;}private:int _b = 1;};class Derive : public Base{public:virtual void Func1(){cout << "Derive::Func1()" << endl;}private:int _d = 2;};int main(){Base b;Derive d;return 0;}

看Visual Studion下的监视窗口。如下图。
在这里插入图片描述
通过对监视窗口的分析可以得出如下结论:

  1. 派生类对象d中也有一个虚表指针,d对象由两部分构成,一部分是父类继承下来的成员,虚表指针也就是存在的部分,另一部分是自己的成员
  2. 基类b对象和派生类d对象虚表是不一样的,这里我们发现Func1完成了重写,所以d的虚表中存的是重写的Derive::Func1,所以虚函数的重写也叫作覆盖,覆盖就是指虚表中虚函数的覆盖。重写是语法的叫法,覆盖是原理层的叫法。
  3. 另外Func2继承下来后是虚函数,所以放进了虚表,Func3也继承下来了,但是不是虚函数,所以不会放进虚表。
  4. 虚函数表本质是一个存虚函数指针的指针数组,一般情况这个数组最后面放了一个nullptr。
  5. 总结一下派生类的虚表生成:a.先将基类中的虚表内容拷贝一份到派生类虚表中 b.如果派生类重写了基类中某个虚函数,用派生类自己的虚函数覆盖虚表中基类的虚函数 c.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类虚表的最后。
  6. 这里还有一个很容易混淆的问题:虚函数存在哪的?虚表存在哪的? 答:虚函数存在虚表,虚表存在对象中。注意上面的回答的错的。 但是很多同学都是这样深以为然的。注意:虚函数表存的是虚函数指针,不是虚函数,虚函数和普通函数一样的,都是存在代码段的,只是他的指针又存到了虚函数表中。另外对象中存的不是虚函数表,存的是虚函数表指针。那么虚表存在哪的呢?代码段! 感兴趣的同学可以用如下代码去打印一下虚表的地址,来验证一下。
typedef void(*VF_PTR)();//void PrintVFTable(VF_PTR table[])
// 打印虚函数表中内容
void PrintVFTable(VF_PTR* table)
{for (int i = 0; table[i] != nullptr; ++i){printf("vft[%d]:%p->", i, table[i]);VF_PTR f = table[i];f();}cout << endl << endl;
}
int main()
{Base b;PrintVFTable((VF_PTR*)(*(void**)&b));Derive d;PrintVFTable((VF_PTR*)(*(void**)&d));return 0;
}

7.在函数调用过程中,对象先找到虚函数表指针,通过该指针找到虚函数表,再在虚函数表中找到对应的函数指针,通过函数指针找到所需要的哪个函数。如下图所示。
在这里插入图片描述

6.2多态的原理

 class Person {public:virtual void BuyTicket() { cout << "买票-全价" << endl; }};class Student : public Person {public:virtual void BuyTicket() { cout << "买票-半价" << endl; }};void Func(Person& p){p.BuyTicket();}int main(){Person Mike;Func(&Mike);Student Johnson;Func(&Johnson);return 0;}

在这里插入图片描述

  1. 观察上图的红色箭头我们看到,p是指向mike对象时,p->BuyTicket在mike的虚表中找到虚函数是Person::BuyTicket。
  2. 观察上图的蓝色箭头我们看到,p是指向johnson对象时,p->BuyTicket在johson的虚表中找到虚函数是Student::BuyTicket。
  3. 这样就实现出了不同对象去完成同一行为时,展现出不同的形态。
  4. 反过来思考我们要达到多态,有两个条件,一个是虚函数覆盖,一个是对象的指针或引用调用虚函数。反思一下为什么?单纯的对象的话所有的对象的虚函数表都是相同的,利用指针或者引用可以看作指向对象当中父类那一部分的成员或者指针。覆盖使其不同的虚表中,指向的虚函数不同,从而完成多种状态
  5. 看出满足多态以后的函数调用,不是在编译时确定的,是运行起来以后到对象的中取找的。不满足多态的函数调用时编译时确认好的。
    !!!一图搞懂多态的原理
    在这里插入图片描述

7.多继承中的虚函数表

 class Base1 {public:virtual void func1() {cout << "Base1::func1" << endl;}virtual void func2() {cout << "Base1::func2" << endl;}private:int b1;};class Base2 {public:virtual void func1() {cout << "Base2::func1" << endl;}virtual void func2() {cout << "Base2::func2" << endl;}private:int b2;};class Derive : public Base1, public Base2 {
public:virtual void func1() {cout << "Derive::func1" << endl;}virtual void func3() {cout << "Derive::func3" << endl;}
private:int d1;};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(){Derive d;VFPTR* vTableb1 = (VFPTR*)(*(int*)&d);PrintVTable(vTableb1);VFPTR* vTableb2 = (VFPTR*)(*(int*)((char*)&d+sizeof(Base1)));PrintVTable(vTableb2);return 0;}

在这里插入图片描述
分析上述图片可以得出如下结论:
1、多继承派生类的未重写的虚函数放在第一个继承基类部分的虚函数表中
2、多继承时,子类重写了Base1和Base2虚函数func1,但是虚函数表中重写的func1的地址却不一样,但是没关系,他们最终还是调到同一个函数。这是因为存在偏移量的问题。

http://www.khdw.cn/news/71173.html

相关文章:

  • 网站建设企业 熊掌号成品网站建站空间
  • 佛山哪个做网站的好优化服务平台
  • 建设银行网站信息补充网络广告营销方案
  • 龙岗网站建设 信科网络网页在线秒收录
  • 做网站 业务流程图本网站三天换一次域名
  • 环球购物官方网站宁波seo网络优化公司
  • 做淘宝详情页的网站口碑推广
  • 有什么网站可以做简历厦门人才网招聘官网
  • 力软框架做网站搜索引擎关键词怎么选
  • 请列出五个以上做外贸的网站杯子软文营销300字
  • 深圳数据中心建设公司windows优化大师可以卸载吗
  • google移动网站建站十大原则网络营销广告案例
  • 单页面网站怎么做营销方案网站
  • 网站系统评测要怎么做呢怎么联系地推公司
  • 公司制作网站怎么做的seo搜索引擎优化价格
  • 校园网站建设 德育免费学生html网页制作成品
  • 太原市网站建设公司网站建设哪家公司好
  • 域名如何购买快速优化关键词排名
  • 如何在社交网站上做视频推广方案seo关键词优化外包公司
  • 网站建设总结体会seo查询系统源码
  • 网站做301好不好电商网络营销
  • 镇江网站优化公司工作室最全磁力搜索引擎
  • 艺术培训学校系统网站怎么做深圳网站建设公司排名
  • 美妆网站建设国外免费网站域名服务器
  • 企业网站在ps里做吗网推拉新app推广接单平台
  • 做国际网站阿里巴巴小说百度风云榜
  • 昆明网络公司网站网络推广员的工作内容和步骤
  • 清理网站数据库百度提交入口的注意事项
  • python做直播网站在百度做广告多少钱
  • 怎么建立淘宝客网站营销策划公司