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 ...
随机推荐
- linux自学(四)之开始centos学习,网络配置
上一篇:linux自学(三)之开启虚拟机 安装好镜像之后,重启之后需要登录,我这里直接是root账号直接登录的,注意:输入密码的时候不显示. 之后输入ifconfig最常用的命令来查看网卡信息,出现c ...
- 让一个 csproj 项目指定多个开发框架
可移植类库.共享项目..NET Standard 项目都能够帮我们完成跨多个 .NET SDK 的单一项目开发,但它们的跨 SDK 开发都有些限制.现在,我们又有新的方式能够跨多个 .NET SDK ...
- Oracle中用exp/imp命令快速导入导出数据
from: http://blog.csdn.net/wangchunyu11155/article/details/53635602 [用 exp 数 据 导 出]: 1 将数据库TEST完全导出, ...
- bat命令1
echo 命令 打开回显或关闭请求回显功能,或显示消息.如果没有任何参数,echo命令将显示当前回显设置. 语法 echo [{on|off}] [message] Sample:@echo off ...
- 三分钟教你同步 Visual Studio Code 设置
简介 Visual Studio Code(以下简称vsCode)现在已经渐渐成为前端开发的主力工具,谁让它这么轻便,功能又这么轻便呢.用vscode Coding的小伙伴们也一定会装很多插件吧. ...
- Nginx配置(需要把nginx的根目录指向ftp上传文件的目录。)
改成
- anycast简单总结
一针见血,言简意赅的总结 bgp+anycast就是不同服务器用了相同的ip地址 anycast 技术特点 bgp+anycast就是多个主机使用相同ip地址的一种技术,当报文发给该地址时,根据路由协 ...
- openresty websocket 使用
openresty websocket 使用 1. 代码如下: local server =require"resty.websocket.server" local wb, ...
- SVN增加文件后,文件无法自动包括在项目中的原因
当增加文件后,不仅要提交所增加的文件,而且要把项目文件一并提交.不然就会出现其他人虽然能够获取新文件,但是文件不能自动加载到项目中的情况.
- 解决Vsphere Client 60天过期问题