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

忆唐网不做网站做品牌网站优化什么意思

忆唐网不做网站做品牌,网站优化什么意思,惠阳网站建设,乐码王国少儿编程加盟尝试修改虚函数表 本期纯整活儿好吧!!!! 初衷 有一天我突然开始好奇虚函数表是否真的存在,于是我开始想是否能够从C中查看或者调用虚函数表中的内容。,于是有了下面的操作。 操作过程 起初我并没有思路…

尝试修改虚函数表

本期纯整活儿好吧!!!!

初衷

有一天我突然开始好奇虚函数表是否真的存在,于是我开始想是否能够从C++中查看或者调用虚函数表中的内容。,于是有了下面的操作。

操作过程

起初我并没有思路,但是我知道,每一个类对应一个虚函数表,因此首先我需要一个虚函数,因此我随便写了一个基类:

class Base {
public:void output() {cout << "Class Base" << endl; };virtual void say() {cout << "Class Base" << endl;}
};

然后写一个子类,去 override 一下他的这个函数:

class A : public Base {
public:void output() {cout << "Class A" << endl;}void say() override {cout << "Class A" << endl;}int x;
};

然后按照同样的方式再创建一个 B 类:

class B : public Base {
public:void output() {cout << "Class B" << endl;}void say() override {cout << "Class B" << endl;}
};

这样以来,应该会有三个虚函数表,分别是:

  • Base基类对应的虚函数表
  • A类对应的虚函数表
  • B类对应的虚函数表

然后如何调用他们呢?我想了好久,想出这样的一个方法:

int main() {A a;B b;cout << "A's virtual table address : " << ((void **)(&a))[0] << endl;cout << "A's virtual table address : " << ((void **)(&b))[0] << endl;return 0;
}

根据理论来说,C++中的虚函数表应该在类内空间的第一个位置,占八个字节,是一个指向函数表的指针,那么我们就应该这样做:

((void **)(&b))[0];

这会返回一个虚函数表的地址。

这句话是什么意思呢?首先我们要清楚,对象的空间分配与结构体是一样的,而根据理论来看,虚函数表的指针会被编译器自动添加在对象空间的初始位置,也就是说,对象所在的空间的第一个单元存储的是虚函数表的地址。

如何获得这个首地址呢?首先我们要像取数组首地址一样,用取地址符号获得对象的首地址。然后将其强制转换为 (void **) 类型,这相当于让电脑将这个对象的空间看作一个数组,这个数组中存放的全部都是指向 void * 类型的数据的地址。

void * 类型是函数指针类型,我们不用管,最后在末尾添加[0]就相当于得到了虚函数表的地址。

尝试输出一下:
1
嗯,看起来没啥问题,但是如何证明他是个虚函数表的地址呢?

我能否将一个类中的修改到另一个虚函数表中?然后让这个对象执行的时候出现另外一个类的动作?

于是我开始了下面的尝试:

int main() {A a;B b;cout << "Class A virtual table address : " << ((void **)(&a))[0] << endl;cout << "Class B virtual table address : " << ((void **)(&b))[0] << endl;((void **)(&a))[0] = ((void **)(&b))[0]; // 把b对应的类的虚函数表覆盖到a上a.say(); // 如果虚函数表被覆盖了的话,那么就会出现a执行了b的say方法的状况b.say();return 0;
}

然而结果是这样的:

2
发现结果并没有被改变,这是怎么回事?我百思不得其解,多方询问过之后了解到是gcc编译器把我的虚函数的调用过程给优化掉了,无奈我只能使用指针和引用来赋值:

int main() {A a;B b;Base *ap = &a, *bp = &b;cout << "Class A virtual table address : " << ((void **)(&a))[0] << endl;cout << "Class B virtual table address : " << ((void **)(&b))[0] << endl;((void **)(&a))[0] = ((void **)(&b))[0]; // 把b对应的类的虚函数表覆盖到a上ap->say(); // 如果虚函数表被覆盖了的话,那么就会出现a执行了b的say方法的状况bp->say();return 0;
}

3
执行成功啦!!!

其实后面我还做了很多好玩的操作,这里先不放出来,写的有点累,下次再凑出一篇来!

:wq 拜拜~~

http://www.mnyf.cn/news/46995.html

相关文章:

  • 加盟网站分页怎么做seoseo推广一年要多少钱
  • 网络诈骗做网站 维护游戏推广代理app
  • 百度医院网站建设网站分析培训班
  • 那些钓鱼网站是怎么做的seo搜索引擎优化方案
  • 电商网站开发长沙seo关键词
  • 帮别人做网站后期维护google关键词seo
  • 泰安网签数据怎样优化网站排名
  • 工厂弄个网站做外贸如何官网首页入口百度
  • php+mysql网站开发免费网站安全检测
  • 潍坊关键词优化服务青岛百度推广优化
  • 郑州app软件开发公司应用商店优化
  • 网站一次性链接怎么做的app推广平台排行榜
  • 网站的角色设置如何做学生网页设计模板
  • 谁家网站做的好免费b站推广网址有哪些
  • 重庆网站备案规则电商网站建设公司
  • 成品ppt的网站免费观看推广普通话宣传语
  • 免费asp网站源码下载今天新疆新闻头条
  • 清远市清城区网站建设公司公司企业网站制作
  • 男女宾馆做爰视频网站什么是网络营销
  • 企业网站如何部署济南优化网站的哪家好
  • 新乡免费网站建设怎么样推广自己的网站
  • 已有网站开发app客户端网络营销做得好的酒店
  • 网站建设发生的费用会计科目建站之星网站
  • 昆山建筑行业网站域名怎么注册
  • 做网站的害处seo1搬到哪里去了
  • 建个人网上银行登录入口青岛推广优化
  • 建站之星登录软件开发培训多少钱
  • 自己弄个网站郑州网络营销公司哪个好
  • 如何做私服网站代理百度收录怎么弄
  • 海口网站制作价格seo 优化一般包括哪些内容