C++利用指针突破私有成员访问限制
C++ 面向对象的一大特性就是封装,使用不同的访问控制符来控制外接对其的访问权限。比如:

1 class A
2 {
3 public:
4 A(): i(10){}
5 void print(){ cout << "A::i = " << i << endl; }
6
7 private:
8 int i;
9 };

这里的A 类对象的 i 对外接来说就是透明的。通过private 来隐藏对象的某些属性。但是,C++也继承了大部分C的特性,比如说很好很强大的指针。利用指针,我们可以绕过编译器做一些 见不得光的事情。虽然不建议这么做,因为这样不仅破坏了数据的封装特性,也会带来很多危险。不过这里我还是这么做了。。。。。
请看下面的这个例子,利用指针p去修改 对象a 的私有成员i 的值:
#include <iostream>
using namespace std; class A
{
public:
A(): i(){}
void print(){ cout << "A::i = " << i << endl; } private:
const int i;
}; int main()
{
A a; int* p = (int*)&a; // 突破编译器的防线
a.print(); *p = ; // 偷偷修改a 对象私有成员的值
a.print(); return ;
}
执行结果:
A::i = 10
A::i = 30
通过打印结果可以看出p 真的做了不该做的事情
这时候有的朋友可能会觉得将A 类中的 i 声明成 const int 指针p应该就无能为力了吧。
事实证明 私有成员变量即使是 const 类型也是无济于事的,他们都无法阻挡指针的穿透力!
参考:http://www.cnblogs.com/CocoonFan/archive/2013/06/22/3149231.html
void Hijack(X &x)
{
x.m_nPrivate = 2;
} class X
{
// 手工添加
friend ::Hijack(X &); // 这里是复制X类定义
private:
int m_nPrivate; public:
X()
: m_nPrivate(1)
{} template<typename T>
void Func(const T &t)
{} const int GetValue()
{
return m_nPrivate;
}
};
#define private public // 万恶的宏伎俩啊 void Hijack(X &x)
{
x.m_nPrivate = 2;
}
他的两根手指头很灵活哟。在VC2008成功执行得到。然而他却有两个违背标准的行为:
1)#define 保留字是非法的
2)违反了但一定以规则(ODR),然而类的底层内存布局没改变,故可行
3.骗子方式
// 同X的内存布局,只有一个int型的变量
class BaitSwitch
{
public:
int m_nNotPrivate;
}; void Func(X &x)
{
(reinterpret_cast(x)).m_nNotPrivate = 2;
}
namespace
{
struct Y{};
} template<>
void X::Func(const Y&)
{
m_nPrivate = 2;
} void Test()
{
X x;
cout << x.GetValue() << endl; x.Func(Y());
cout << x.GetValue() << endl;
}
C++利用指针突破私有成员访问限制的更多相关文章
- [转载] C++ 突破私有成员访问限制
最后一个方式 模板尚未弄清楚. 我们在写代码的时候,按约定都是把成员数据放到private访问区中,然后在通过相应的函数来存取.那又有什么样的代码可以突破访问权限来直接操作类中private区段中的成 ...
- 利用指针突破C++编译器的防线
C++ 面向对象的一大特性就是封装,使用不同的访问控制符来控制外接对其的访问权限.比如: class A { public: A(): i(){} void print(){ cout << ...
- C++ //继承中的对象模型 //利用开发人员命令提示工具查看对象模型 //父类中所有非静态成员属性都会被 子类继承下去 //父类中私有成员属性 是被编译器给隐藏了 因此是访问不到 但是确实被继承下去了
1 //继承方式 2 //语法:class 子类 :继承方式 父类 3 //继承方式 三种: 4 //1.公共继承 5 //2.保护继承 6 //3.私有继承 7 8 /* 9 #include &l ...
- 使用C#反射机制访问类的私有成员【转】
首先我必须承认访问一个类的私有成员不是什么好做法.大家也都知道私有成员在外部是不能被访问的.而一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员访问,可以套用下面这种非常好的方式 ...
- C#中访问私有成员--反射
首先我必须承认访问一个类的私有成员不是什么好做法.大家也都知道私有成员在外部是不能被访问的.而一个类中会存在很多私有成员:如私有字段.私有属性.私有方法.对于私有成员访问,可以套用下面这种非常好的方式 ...
- 通过指针访问C++对象的私有成员
C++对象的私有成员是禁止类外的访问的.但是我们仍然可以通过指针访问C++对象的私有成员. #include <iostream> using namespace std; class A ...
- CPP-基础:关于私有成员的访问
a.C++的类的成员函数中,允许直接访问该类的对象的私有成员变量. b.在类的成员函数中可以访问同类型实例的私有变量. c.拷贝构造函数里,可以直接访问另外一个同类对象(引用)的私有成员. d.类的成 ...
- java中用反射访问私有方法和私有成员[转]
转自: http://zhouyangchenrui.iteye.com/blog/470521 java的反射可以绕过访问权限,访问到类的私有方法和成员.可能这点会引起安全性的讨论.反射的使用帮助解 ...
- VC6.0中友元函数无法访问类私有成员的解决办法
举个例子: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 #inclu ...
随机推荐
- Java 学习 第三篇;面向对象
1:Java的常用包: 核心类在java 包中:扩展类在javax包中 java.lang 系统默认自动导入 包含String Math System Thread等类 java.util 包含了工具 ...
- UFI命令格式里SCSI指令
有三种字长命令:6位.10位.12位,一般Windows下用12位. 在UFI 命令格式里SCSI指令用到如下: 指令代码 指令名称 说明 04h Format Unit 格式化存储单元 12h In ...
- C# dynamic类型
dynamic类型是C#4.0中引入的新类型,它允许其操作掠过编译器类型检查,而在运行时处理.dynami类型在绝大多数情况下和object类型相似,不同之处在于编译器对于包含了dynamic的表达式 ...
- 【Razor语法规则小手册....】
在经过长达半年的Windows开发后,Razor的一些语法有些生疏了.搜集些,再熟悉下.呵呵,甚是怀念以前做web 项目的时候,基于动软代码生成器自定义T4模板,后来vs2010后开始支持T4模板. ...
- Linux删除乱码文件或者目录
Linux删除乱码文件或者目录 有时在Linux下面解压一些zip或者rar文件后会产生乱码文件或者目录,这个时候使用rm不能成功删除,需要使用一些特别的方法 来进行删除,下面是我经常使用的两种方法. ...
- 【排序】表插入排序算法(C语言版)
排序耗时的操作主要分为两种:查找比较.记录移位. 1.表插入排序 在查找比较基础上,尽量减少记录移位步数,可以令排序操作耗时降低,表插入排序正是为减少移位次数而出现的. 在数据结构上,数据是存储在静态 ...
- STL源码剖析读书笔记之vector
STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...
- sshd安全性能优化
sshd服务是远程登录服务,默认端口为22,对于其优化一是为了增加服务器的安全,避免暴力破解:二是为了加快速度连接,减少不必要的带宽的浪费. sshd服务的配置文件为/etc/ssh/sshd_con ...
- 使用react-native做一个简单的应用-02项目搭建与运行
下面我们开始着手去做这一个项目,因为初学不久就开始边学边做,所以有些地方设计不太合理.请大家多多包涵.0.0 下面来介绍截图中的三个文件夹, GuoKuApp:是我开发app的文件夹. GuoKuDB ...
- C#实现WinForm传值实例解析
C#实现WinForm传值的问题经常会做为公司面试的题目,那么作为学习C#以及WinForm传值,我们需要掌握哪些方法和思路呢?下面我们就向你介绍详细的思路和实现的具体步骤,希望对你有所帮助. C#实 ...