C++虚函数表理解
一,思维模式图

二,代码验证
class A {
public:
A(int x) {
fProtected = x;
}
float GetFProtected() {
return fProtected;
}
public:
float fpublic = 2.3f; //c++11支持了初始化,但不能使用auto
string sname = "liqi";
CMyNumOperator<int>* on = new CMyNumOperator<int>(); //对象也可以
void TestFunc() {
cout << "TestFunc" << endl;
}
static void StaticTestFunc() {
cout << "Static-TestFunc" << endl;
}
virtual void ToString() {
cout << "A::ToString" << endl;
}
protected:
float fProtected;
void ProtectedFunc() {
cout << "PRotectedFunc" << endl;
}
private:
void PrivateFunc() {
cout << "PrivateFunc" << endl;
}
};
//只管公有继承,不管保护继承和私有继承,意义不大,也太复杂
class B : public A {
public:
friend void TestProtectedDerive();
B() :A() {}
void TestForDerive() {
//公有继承下
//1,子类可以访问父类的保护成员,不能访问父类的私有成员
B ob;
//PrivateFunc(); //error,子类不能访问基类的私有成员
ProtectedFunc(); //right
fProtected = ; //right
ob.fProtected = ; //right
}
//1,c++中只要基类有相同签名虚函数,则默认为此基类函数也是虚函数[与C#不同],如下情形都成立
// (1) 函数不声明 virtual
// (2) 函数声明了 virtual
// (3) 函数声明了 override
// (4) 函数声明了 virtual 和 override
//2,c++中两个关键词作用不同,可以同时存在
// virtual仅表明函数是虚函数,override是C++11中出现的,明确说明是对基类的重写
// 它的好处是当函数声明不符合规则时,编译器会报错
void virtual ToString() override{
cout << "B::ToString" << endl;
}
};
void TestVirtualFunctionTable() {
cout << hex;
typedef void(*PFUNC)();
offsetof(A, fpublic); //利用此函数可以算函数布局
A oa();
B ob;
//一,通过内存地址修改不可访问的保护变量
*(float*)((int*)&oa + ) = 123.4f; //类的第一个变量fpublic赋值,(int*)&oa + 1是跳过虚函数指针
float fpublic = oa.fpublic;
//二,通过内存地址调用虚函数
//A和B的虚函数表地址不一样,也就是说父类和子类各有一张虚函数表
int* pvptr = (int*)(*((int*)(&oa)));
cout << "A的虚函数表地址:" << pvptr << endl; //000DB0D4
((void(*)())(*pvptr))(); //A::ToString
pvptr = (int*)(*((int*)(&ob)));
cout << "B的虚函数表地址:" << pvptr << endl; //000DB128
((void(*)())(*pvptr))(); //B::ToString
cout << "--------------------------" << endl;
//最简写法
((void(*)())(*((int*)*(int*)&oa)))();
((void(*)())(*((int*)*(int*)&ob)))();
}
C++虚函数表理解的更多相关文章
- 深入理解C++虚函数表
虚函数表是C++类中存放虚函数的一张表,理解虚函数表对于理解多态很重要. 本次使用的编译器是VS2013,为了简化操作,不用去操作函数指针,我使用到了VS的CL编译选项来查看类的内存布局. CL使用方 ...
- 从逆向的角度去理解C++虚函数表
很久没有写过文章了,自己一直是做C/C++开发的,我一直认为,作为一个C/C++程序员,如果能够好好学一下汇编和逆向分析,那么对于我们去理解C/C++将会有很大的帮助,因为程序中所有的奥秘都藏在汇编中 ...
- 我理解的C++虚函数表
今天拜读了陈皓的C++ 虚函数表解析的文章,感觉对C++的继承和多态又有了点认识,这里写下自己的理解.如果哪里不对的,欢迎指正.如果对于C++虚函数表还没了解的话,请先拜读下陈皓的C++ 虚函数表解析 ...
- 对C++虚函数、虚函数表的简单理解
一.虚函数的作用 以一个通用的图形类来了解虚函数的定义,代码如下: #include "stdafx.h" #include <iostream> using name ...
- 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)
本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上? 成员函数可以被看作是类 ...
- C++ 虚函数表与内存模型
1.虚函数 虚函数是c++实现多态的有力武器,声明虚函数只需在函数前加上virtual关键字,虚函数的定义不用加virtual关键字. 2.虚函数要点 (1) 静态成员函数不能声明为虚函数 可以这么理 ...
- C++虚函数及虚函数表解析
一.背景知识(一些基本概念) 虚函数(Virtual Function):在基类中声明为 virtual 并在一个或多个派生类中被重新定义的成员函数.纯虚函数(Pure Virtual Functio ...
- 关于C++中虚函数表存放位置的思考
其实这是我前一段时间思考过的一个问题,是在看<深入探索C++对象模型>这本书的时候我产生的一个疑问,最近在网上又看到类似的帖子,贴出来看看: 我看到了很多有意思的答案,都回答的比较好,下面 ...
- c++ 继承类强制转换时的虚函数表工作原理
本文通过简单例子说明子类之间发生强制转换时虚函数如何调用,旨在对c++继承中的虚函数表的作用机制有更深入的理解. #include<iostream> using namespace st ...
随机推荐
- BZOJ1220 HNOI2002 跳蚤 【容斥原理+高精度】*
BZOJ1220 HNOI2002 跳蚤 Description Z城市居住着很多只跳蚤.在Z城市周六生活频道有一个娱乐节目.一只跳蚤将被请上一个高空钢丝的正中央.钢丝很长,可以看作是无限长.节目主持 ...
- BZOJ1131 POI2008 Sta 【树形DP】
BZOJ1131 POI2008 Sta Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=10 ...
- WampServer的配置
转自:http://www.cnblogs.com/azumia/archive/2012/06/06/2538872.html 第一,打开局域网访问 配置文件:点击右下角的WAMP 服务器小托盘,选 ...
- android 和主线程有关的小问题
1.在android 中 HTTP请求被不允许在主线程中执行,否则会抛出异常.如果请求时间过长,阻塞UI线程是一个非常差的体验之前,刚开始开发遇到这个问题,每次app运行到最后,发送网络请求就自己崩溃 ...
- 【requirejs】JS模块化工具requirejs教程
初识requirejs 随着网站功能逐渐丰富,网页中的js也变得越来越复杂和臃肿,原有通过script标签来导入一个个的js文件这种方式已经不能满足现在互联网开发模式,我们需要团队协作.模块复用.单元 ...
- pthread中读写锁
读写锁很像一个互斥量,他阻止多个线程同时修改共享数据的另一种方法,区分不同互斥量的是他是分读数据和写数据,一个读写锁允许同时多个线程读数据,只要他们不修改数据. 只要没有写模式下的加锁,任意线程都可以 ...
- tomcat日志分类
综合:Tomcat下相关的日志文件 Cataline引擎的日志文件,文件名catalina.日期.log Tomcat下内部代码丢出的日志,文件名localhost.日期.log(jsp页面内部错误的 ...
- (四)、Fiddler打断点
一.打断点是Fiddler一个比较好用的功能,它可以做一些手工操作很难做的事情. 那为什么要打断点? 看下图,Fiddler打开后,Client(客户端)发送的请求会先经过Fiddler,然后Fidd ...
- javascript系列学习----对象相关概念理解
1.构造函数(相对于面向对象编程语言里面的类) 2.对象实例(它是由构造函数构造出来的对象,使用到关键字 new) 3.this关键字(往往是指我们的对象本身) 下面我们来看一个实例: var Per ...
- WebApi和Andriod对接访问模式问题
最近在做WebApi和Andriod接口的对接,中途出现一个问题就是返回格式的问题.由于之前使用WebService的时候使用的一直都是json的序列化和反序列话格式,所以一开始在webapi中通样使 ...