企业即时通讯 - Enterprise Instant Messenger

局域网聊天工具,文字讯息、文件发送、语音通讯、高清视频通讯、远程桌面控制。

用户操作
[即时聊天] [发私信] [加为好友]
FreeEIM StudioID:i_like_cpp
972412次访问,排名32,好友4人,关注者7人。
i_like_cpp的文章
原创 888 篇
翻译 4 篇
转载 69 篇
评论 1148 篇
FreeEIM Studio的公告
最近评论
ScanerKi:#include <stdio.h>

int asm(int s)
{
int t=0;
__asm
{
mov eax, DWORD PTR [ebp+8] ;把s的值传给eax
mov t, eax ;把eax的值传给t
}
printf("- %d……
li_delong:谢谢
li_delong:谢谢
li_delong:谢谢
XUETUJIAN:
文章分类
收藏
相册
EIM 截图
相关软件图片
PI的最精确值
FreeEIM 标签
FreeEIM华军下载
XP SP2 SDK
下载FreeEIM
盛天龙
飞鸽传书
不错的网站
CPPBLOG
局域网聊天
泡妞专家
用VC写Assembly代码(RSS)
百度的Blog(RSS)
存档
软件项目交易
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 C++中直接存取类私有成员[360度]收藏

新一篇: 用__asm写c函数[秋镇菜] | 旧一篇: 怎样和朋友寒暄

本文谈到的问题是,在C++中究竟有没有办法访问类的私有成员,以及如何实现。主要针对菜鸟,老鸟们就不要看了。

 读到《C++编程思想》48页,“3.4 对象布局”一节时,看到这样一段话:
 
 存取指定符是struct的一部分,他并不影响这个struct产生的对象,程序开始运行时,所有的存取指定信息都消失了。存取指定信息通常是在编译期间消失的。在程序运行期间,对象变成了一个存储区域,别无他物,因此,如果有人真的想破坏这些规则并且直接存取内存中的数据,就如在C中所做的那样,那么C++并不能防止他做这种不明智的事,它只是提供给人们一个更容易、更方便的方法。

 既然是在编译期间去掉了所有的存取限制属性,那么能不能设计一段代码绕过编译器的检查机制,又能在运行期间访问类的私有成员呢? 首先想到了条件转移语句——编译器对条件转移代码块的编译是否有可利用之处呢?虽然实验失败了,但我的第一想法确实是这个。示例代码如下:
//tester.h
//Demo class
class tester
{
public:
 tester() : i(5), ch('x'){};
private:
 int i;
 char ch;
};

//test1.cpp
//Demo testing code

#include "tester.h"
#include<conio.h>
#include<iostream>

using namespace std;

void main(void)
{
 tester myTester;
 char* p = NULL;

 if (1 > 0)
 {
  p = &myTester.ch;  //Here is the point
 }

 cout << "Address of ch = " << (void*) p << endl; //The type modifier void* forces it to output the
              //address, not its  content
 cout << "ch = " << * (p) << endl;

 getch();  //Waits your action
 * p = 'y';

 cout << "Now ch = " << * (p) << endl;
}
 结果正如上面所说,失败了:编译器报错:error C2248: 'ch' : cannot access private member declared in class 'tester'。不过这引发了更深一步的思考。C语言里面最活的就是指针了,平常最怕乱指的野指针,这一次就试试它!修改后的测试代码如下:

//test2.cpp
//Demo testing code

#include "tester.h"
#include<conio.h>
#include<iostream>

using namespace std;

void main(void)
{
 tester myTester;
 char* p = NULL;

 p = (char*) &myTester + sizeof(int);  //Here is the point! Jumps sizeof(int) units of bytes!

 cout << "Address of ch = " << (void*) p << endl; //The type modifier void* forces it to output the
              //address, not the content.
 cout << "ch = " << * (p) << endl;

 getch();  //Waits your action
 * p = 'y';

 cout << "Now ch = " << * (p) << endl;
}
 查看输出后可以发现,ch的内容已经修改了。不过通过指针强行访问类的私有成员确实有点那个,嘿嘿。

发表于 @ 2006年01月24日 17:43:00|评论(loading...)|编辑

新一篇: 用__asm写c函数[秋镇菜] | 旧一篇: 怎样和朋友寒暄

评论

#乱 发表于2006-01-25 14:42:00  IP: 210.82.77.*
没啥意义,既然代码是你写的,为啥不直接public
#秋镇菜 发表于2006-01-25 17:57:00  IP: 218.18.212.*
晕~万一你派生人家的类,怎么办?
#ccmaster 发表于2006-02-03 11:49:00  IP: 222.71.41.*
指针p的偏移量sizeof(int),是因为只有一个成员函数,多个成员函数怎么办?
#?? 发表于2006-02-14 11:19:00  IP: 218.80.127.*
偏移量是个前面的整形成员变量,多个的话直接看头文件的声明就可以了,只是不知道多个变量和多个成员函数在一起同时声明public和privite会怎样,成员函数的话返回的偏移量和变量应该是一样的吧,唉,再试试看,懂得还不多啊
#ride 发表于2006-02-16 14:23:00  IP: 210.83.15.*
用私有变量就是使用它的包装,你这样破坏了包装的含义,还有什么意义?
#harly 发表于2006-02-18 09:29:00  IP: 222.240.65.*
同意楼上的观点,既然是私有变量,就没必要被这样利用吧。不过楼主的想法确实不错。
#pro 发表于2006-02-26 16:19:00  IP: 222.240.21.*
还是不要这样的好,
#silekey 发表于2006-02-27 11:51:00  IP: 203.86.18.*
//没啥好说的.
class CT1
{
public:
Print(){cout<<a<<endl;}
private:
int a;
};
struct CT2
{
private:
int a;
};

void main()
{
CT1 hehe;
CT2 *xixi=(CT2 *)(&hehe);
xixi->a = 100;
hehe.Print();
}
#aaaaaaaaaaaa 发表于2006-03-09 15:30:00  IP: 222.66.13.*
// testt.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
using namespace std;

class A{
public:
A(){xx=1;}
void print(){cout<<xx<<endl;}
private:
int xx;
};
class B{
public:
B(){yy=2;}
void print2(){cout<<yy<<endl;}
//private:
int yy;
};
int _tmain(int argc, _TCHAR* argv[])
{
A a;
B* b;
b = (B*)&a;
b->print2();
b->yy = 10;

a.print();

system("PAUSE");
return 0;
}
发表评论  


登录
Csdn Blog version 3.1a
Copyright © FreeEIM Studio