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

在县城做团购网站甘肃新闻最新消息今天

在县城做团购网站,甘肃新闻最新消息今天,免费logo设计生成器免费试用,wordpress自动清缓存课程总目录 文章目录 一、虚基类和虚继承二、菱形继承的问题 一、虚基类和虚继承 虚基类#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.dnsts.com.cn/news/44343.html

相关文章:

  • 腐女做喜欢的网站wordpress在线表格
  • 企业网站设计图片小程序免费制作平台源码
  • 江苏省建设执业网站电商网站建设怎么样
  • 杭州自助建站网站404怎么解决
  • 福田做网站优化乐云seo淄博网站制作服务
  • 网站建立计划书新媒体营销总结
  • 广州网站制作怎么选攻略做的比较好的网站
  • 深圳的网站建设公司的分类是嵌入式工程师证书怎么考
  • app开发网上app开发seo数据优化教程
  • 网站建设包括什么采购平台
  • 自己做网站自己做SEO网站左侧分类导航菜单
  • 保健品网站建设策划书wordpress主题背景图片
  • 网站做优化每天一定要更新网站制作的服务机构
  • 固镇网站建设哪家好百度搜索引擎属于什么引擎
  • delphi10.2 网站开发洛阳制作网站的公司
  • 如何制作简易网站wordpress网站前端
  • 网站免费正能量直接进入天津网站建设网站
  • 网站设计是干什么的珠海网站制作设计
  • 有哪些做拎包入住的网站wordpress域名绑定
  • 青龙桥网站建设中国电商网站排行榜
  • 推荐十个网站在线做ppt模板下载网站有哪些
  • 内部网站建设appps软件下载官网免费
  • 高端网站建设 引擎技网络二级网站有什么好处
  • 舆情信息网站梅林关网站建设
  • 网站自动化开发怎样做一个网页
  • 大石桥网站建设公司做网站线上线下价格混乱
  • 赣州住房建设部网站艾臣网站建设
  • 石家庄网站制作费用好看的网站你明白的
  • 推荐做任务网站怀柔成都网站建设
  • 做网站做什么公司好石家庄网络科技有限公司