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

在县城做团购网站免费纯ftp空间

在县城做团购网站,免费纯ftp空间,网页效果制作,台州网站制作教程课程总目录 文章目录 一、虚基类和虚继承二、菱形继承的问题 一、虚基类和虚继承 虚基类#xff1a;被虚继承的类#xff0c;就称为虚基类 virtual作用#xff1a; virtual修饰成员方法是虚函数可以修饰继承方式#xff0c;是虚继承#xff0c;被虚继承的类就称为虚基类… 课程总目录 文章目录 一、虚基类和虚继承二、菱形继承的问题 一、虚基类和虚继承 虚基类被虚继承的类就称为虚基类 virtual作用 virtual修饰成员方法是虚函数可以修饰继承方式是虚继承被虚继承的类就称为虚基类 注意与抽象类有纯虚函数的类区分开来 来看这段代码 class A { public: private:int ma; };class B : public A { public: private:int mb; }; //A a; 4个字节 //B b; 8个字节使用指令cl xxx.cpp -d1reportSingleClassLayoutA和cl xxx.cpp -d1reportSingleClassLayoutB看一下 如果采用虚继承 class B : virtual public A再来看一下B从8字节变为了12字节了 分析当我们遇到虚继承时候要考虑派生类B的内存布局时首先我们先不考虑虚继承。类B继承了基类A的ma还有自己的mb当我们基类A被虚继承后基类A变为虚基类虚基类的数据一定要被挪到派生类数据的最后面再在最前面添加一个vbptr 来看一些例题 class A {}; sizeof(A)1 //空类大小是1class B : public A {}; sizeof(B) 1class A {virtual void fun() {} }; sizeof(A)1class B : public A {}; sizeof(B) 4 //B的内存里有vfptrclass A {virtual void fun() {} }; sizeof(A)1class B : virtual public A {}; sizeof(B) 8 //B的内存里有vfptr和vbptr总结 vfptr一个类有虚函数这个类生成的对象就有vfptr指向vftablevbptr派生类中虚继承基类会有vbptrvftable存放RTTI指针指向运行时RTTI信息、虚函数地址。vbtable第一行为向上偏移量第二行为vbptr离虚基类数据在派生类内存中的偏移量。 接下来再来看当虚基类指针与虚函数指针在一起出现的时候会发生什么呢 class A { public:virtual void func() { cout call A::func endl; } private:int ma; };class B : virtual public A { public:void func() { cout call B::func() endl; } private:int mb; };int main() {// 基类指针指向派生类对象永远指向的是派生类中基类部分数据的起始地址A* p new B();p-func();delete p;return 0; }可以看到调用是没有被影响到的但是delete会出错 分析 B的内存布局B首先从A中获取vfptr与maB中还有自己的mb 此时A被虚继承从A中继承来的所有的东西都移动到派生类的最后面然后在最前面补一个vbptrvbptr指向vbtablevfptr指向vftable 基类指针指向派生类对象永远指向的是派生类基类部分数据的起始地址 普通情况下派生类内存布局先是基类数据再是派生类自己的数据基类指针指向派生类对象时基类指针指向的就是派生类内存的起始部分。 但是在虚继承下基类为虚基类虚基类的数据被挪到派生类最后面最前面补上vbptr此时再用基类指针指向派生类对象时候基类指针还是指向派生类基类部分数据的起始地址也即指向vfptr这也是能正常调用p-func();的原因 那么在释放内存的时候呢现在p指向的是vfptr从vfptr开始释放内存而对象内存现在是从vbptr开始这就出错了 验证一下 class A { public:virtual void func() { cout call A::func endl; }void operator delete(void* p){cout operator delete p: p endl;free(p);} private:int ma; };class B : virtual public A { public:void func() { cout call B::func() endl; }void* operator new(size_t size){void* p malloc(size);cout operator new p: p endl;return p;} private:int mb; };int main() {// 基类指针指向派生类对象永远指向的是派生类中基类部分数据的起始地址。A* p new B();cout main p: p endl;p-func();delete p;return 0; }operator new p:00D316A0 main p:00D316A8 call B::func() operator delete p:00D316A8可以看到从A0开始new的返回给p的是A8delete的时候也是A8也就是从vfptr开始释放的这是不对的 但是这段代码也能说是错的这和编译器有关在Windows的vs中是从vfptr开始释放的但是在linux的g下会自动偏移到new出来的内存的起始部分来进行释放 如果在栈上开辟内存基类指针指向派生类对象出了作用域自己进行析构不涉及内存的释放这样是没有问题的正常运行不会报错 B b; A *p b; cout main p: p endl; p-func();运行结果 main p:010FFE04 call B::func()使用命令cl xxx.cpp -d1reportSingleClassLayoutB查看一下 再来看这时有人会问了派生类为啥不像下面这样画呢 如果是这样画也就是vfptr属于B的作用域这是不对的因为A中有虚函数vfptr是从A中继承而来的 如果真的这样画的话那就是基类中没有虚函数从派生类中才有的虚函数 二、菱形继承的问题 多重继承可以复用多个基类的代码到派生类中 但是多重继承中也会出现问题菱形继承、半圆形继承等 这些都会导致派生类有多份间接基类的数据此时可以采用虚继承来解决 菱形继承代码 class A { public:A(int data) : ma(data) { cout A() endl; }~A() { cout ~A() endl; } protected:int ma; }; // class B : public A { public:B(int data) : A(data), mb(data) { cout B() endl; }~B() { cout ~B() endl; } protected:int mb; };class C : public A { public:C(int data) : A(data), mc(data) { cout C() endl; }~C() { cout ~C() endl; } protected:int mc; }; // class D : public B, public C { public:D(int data) : B(data), C(data), md(data) { cout D() endl; }~D() { cout ~D() endl; } protected:int md; };int main() {D d(10);return 0; }运行结果 A() B() A() C() D() ~D() ~C() ~A() ~B() ~A()来看一下D的内存布局 用指令cl xxx.cpp -d1reportSingleClassLayoutD看看 可以看到调用了两次A的构造同时数据重复了 怎么解决呢虚继承 class A { ... }; // class B : virtual public A { ... }; class C : virtual public A { ... }; // class D : public B, public C { ... };此时内存布局变了解决了多份数据的问题 用指令cl xxx.cpp -d1reportSingleClassLayoutD看看 但是注意此时编译会报错因为现在A::ma靠在了D的作用域上面我们要在D里面给A初始化 class D : public B, public C { public:D(int data) : A(data), B(data), C(data), md(data) { cout D() endl; }~D() { cout ~D() endl; } protected:int md; };再运行看一看结果 A() B() C() D() ~D() ~C() ~B() ~A()多重继承的好处可以做更多代码的复用比如上面的例子D继承自B和C那么就可以B* p new D();或C* p new D();有两个基类两个基类指针都可以指向派生类对象
http://www.hkea.cn/news/14550777/

相关文章:

  • 网站开发 flex邯郸信息港征婚
  • 杭州余杭区网站建设淘宝客怎么做直播网站吗
  • 旅游网站做精准营销的凯里门户网
  • 好用的网站后台管理系统企业网站制作哪些公司制作
  • 什么是网站ip地址张店网站建设公司
  • 个人html网站深圳网站设计兴田德润优惠吗
  • 广州新塘网站建设房地产中介网站
  • 电子商务网站开发实南京市工程造价信息网
  • 一个网站做多少关键词个人网站可以做企业宣传
  • 提升审美网站齐鲁石化建设公司官网
  • php做网站主要怎么布局免费的简历模板大全
  • 什么是灰色网站thinkphp5菜鸟教程
  • 杭州本地品牌网站建设收费网站 兼容性
  • 杭州网站建设很 棒安卓版网页制作软件
  • 小程序怎么做电影网站整合网络营销外包
  • 做二手元器件那个网站查价格深圳制作网站软件
  • php 网站 上传到空间品牌推广是什么
  • 自己做的网站怎么维护软文发布平台哪个好
  • 网站开发工程师需要具备的综合素质wordpress微信公众号
  • 兰州公司网站制作电脑软件下载
  • 国外做的好的电商网站推荐网站设计的设计方案
  • 可以免费打广告的网站2小时学会php网站建设
  • 天津网站建站公司网站栏目 英文
  • 百度网站排名优化工具erp系统华为
  • 全球域名山西常见网站建设推荐优化
  • 网站开发包括网站的wordpress movie
  • 内江 网站建设微信网站怎样做
  • 建设银网站免费建站工具
  • 佛山市南海区建设局网站门户网站模板源代码
  • 专门做家教的网站杭州网站建设培训班