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

郑州网站建设乙汉狮网络枫林seo工具

郑州网站建设乙汉狮网络,枫林seo工具,公司网页网站建设ppt模板下载,网站现状如何分析注:visual studio复制当前行粘贴到下一行: CTRLD 杂项 调用子类重写的虚函数(带默认参数),但参数用的是基类的虚函数中的默认参数: 这是由于参数是在编译时压入 试题一 交换两个基类指针指向的对象的vf…

注:visual studio复制当前行粘贴到下一行: CTRL+D

杂项

调用子类重写的虚函数(带默认参数),但参数用的是基类的虚函数中的默认参数:

这是由于参数是在编译时压入

试题一

交换两个基类指针指向的对象的vfptr造成的运行结果变化

class Animal
{
public:Animal(string name) :_name(name) {}// 纯虚函数virtual void bark() = 0;
protected:string _name;
};
// 以下是动物实体类
class Cat : public Animal
{
public:Cat(string name) :Animal(name) {}void bark() { cout << _name << " bark: miao miao!" << endl; }
};
class Dog : public Animal
{
public:Dog(string name) :Animal(name) {}void bark() { cout << _name << " bark: wang wang!" << endl; }
};int main()
{Animal* p1 = new Cat("加菲猫");Animal* p2 = new Dog("二哈");int* p11 = (int*)p1;int* p22 = (int*)p2;int temp = p11[0]; // p11[0]访问Cat的前4个字节,即 指向Cat的vftable的vfptrp11[0] = p22[0];  // p22[0]访问Dog的前4个字节,即 指向Dog的vftable的vfptrp22[0] = temp;// 上面代码相当于交换了虚函数表指针// 导致下面调用虚函数时就发生了非预期的情况p1->bark(); // 实际调用Dog::bark()p2->bark(); // 实际调用Cat::bark()delete p1;delete p2;return 0;
}

试题二

有如下代码

#include <iostream>
#include <string>
using namespace std;class Base
{
public:virtual void show(int i = 10){cout << "call Base::show i:" << i << endl;}
};
class Derive : public Base
{
public:void show(int i = 20){cout << "call Derive::show i:" << i << endl;}
};
int main()
{Base* p = new Derive();p->show();delete p;return 0;
}
// 输出结果
// call Derive::show i:10

发现调用的是派生类覆盖的函数,确实是动态绑定,但使用的参数却是基类虚函数的默认参数,而不是派生类重写的虚函数的默认值。

原因是函数调用参数压栈是在编译时期,具体call函数可以在运行时,p->show() 汇编指令大致如下:

push 0Ah # 压入基类的默认实参10
mov eax, dword ptr[p]
mov ecx, dword ptr[eax]
call ecx

试题三

利用多态能调用到派生类private成员函数

#include <iostream>
#include <string>
using namespace std;class Base
{
public:virtual void show(int i = 10){cout << "call Base::show " << endl;}
};
class Derive : public Base
{
private:void show(int i = 20){cout << "call Derive::show" << endl;}
};
int main()
{Base* p = new Derive();// 成员方法限定符是在【编译时】检查,由于编译时通过p检查的是Base::show(),没有问题// 而运行时调用子类覆盖的成员这不影响函数执行p->show(); // 最终调用到Derive::show(),是在运行时期确定delete p;return 0;
}// 输出结果:call Derive::show

如果把基类的虚函数访问权限设置为private,则在编译阶段无法通过

试题四

说明下面代码段一和二是否正确执行,说明理由

#include <iostream>
#include <string>
using namespace std;class Base
{
public:Base(){cout << "call Base()" << endl;clear();}// !!!!!!!!!!!!!!!!!!!!!!!!void clear() { memset(this, 0, sizeof(*this)); }virtual void show(){cout << "call Base::show()" << endl;}
};
class Derive : public Base
{
public:Derive(){cout << "call Derive()" << endl;}void show(){cout << "call Derive::show()" << endl;}
};
int main()
{// 代码段一Base* pb1 = new Base();pb1->show();delete pb1;// 代码段二/*Base* pb2 = new Derive();pb2->show();delete pb2;*/return 0;
}

解答:

代码段一执行失败

因为new Base()调用构造函数时,进入第一行代码前会生成vfptr(就是将vftable地址写入其中),指向Base类对应的虚函数表,但是在构造函数中后面又调用clear函数将内存清0,导致vfptr被置零,随后调用 pb1->show(); 时会使用vfptr则会造成非法访问,运行时提示:

引发了异常: 读取访问权限冲突。

pb1->**** 是 nullptr

代码段二执行成功

执行 new Derive(); 时先调用基类构造,虽然在构造函数中也会使vfptr被清零,但是随后调用派生类构造会将子类的vftable地址赋值给vfptr,所以导致最后通过 pb2->show(); 访问vfptr是没问题的

http://www.wangmingla.cn/news/132110.html

相关文章:

  • 做暧暧小视频有声音的网站某网站搜索引擎优化
  • 长沙建网站速成班互联网营销平台
  • 用wordpress建站案例c++线上培训机构哪个好
  • 开发商城网站公司微信朋友圈营销方案
  • 企业网站 三网系统发外链比较好的平台
  • 静安网站建设深度搜索
  • 网站建立健全举报工作机制seo网站优化工具
  • 手机app软件怎么开发临沂网站建设优化
  • 宜昌教育培训网站建设域名检测查询
  • 北京专业做网站推广晋江怎么交换友情链接
  • 普洱北京网站建设鼓楼网页seo搜索引擎优化
  • 儋州市住房和城乡建设局官方网站百度移动应用
  • 购物商城网站设计方案个人网站免费域名注册
  • 腾讯新闻最新消息山东seo网页优化外包
  • 加强网站内容建设的意见谷歌推广方案
  • 网站网站建设网站北京推广服务
  • 北京哪个公司做网站好青岛网络优化代理
  • 深圳做营销网站的公司简介发外链比较好的平台
  • 网站设置超链接杭州seo网络公司
  • 成都门户网站建设西安专业网络推广公司
  • 汕头网站建设浩森宇特搜狗网页
  • 云南网站做的好的公司简介大数据是干什么的
  • 湾里南昌网站建设公司app怎么开发出来的
  • 深圳网站建设服务公互联网营销师怎么考
  • 动易政府网站管理系统解决方案网站品牌推广策略
  • 简单flash网站模板百度爱采购官网首页
  • 网站开发存在的风险网络营销的推广方式都有哪些
  • 泰安红河网站建设十大搜索引擎排名
  • 多合一建网站seo工资
  • 个人网站怎样做超链接正规app推广