如何访问私有成员变量和函数

原创 2007年01月28日 12:39:00

一说到修改 Delphi 源码或者访问对象的私有成员函数,很多人马上可以说出种种危害来否定我。这种做法我也提倡,但是有时候如果可以灵活运用,可以解决由于 Delphi 因为封装不正确而带来的问题。我在这里分享一些技巧:

1.     访问私有成员变量
如果是 protected 的变量,可以用如下方法访问:

type
  TSomeClassAccess = 
class(TSomeClass);

begin
  TSomeClassAccess(Object1).protected_Bool := False;
  TSomeClassAccess(Object1).protected_Int := 
0;
  ...
end;

如果是 private 的变量,那么就要当心了。因为涉及到偏移量。还要考虑不同 Delphi 版本的控件的内部成员可能也有变化。最简单的例子是:访问 TMenuItem 的第二个内部成员变量 FHandle

type
  THackMenuItem = 
class(TComponent)
  
protected //<-- change to protected 
    FxxxxCaption: AnsiString;
    FHandle: HMENU;
//<-- the property you want to access

  end;


begin
  THackMenuItem(AMenuItem).FHandle := 0;
  ...
end;

2.      访问私有成员函数
这个目前普遍的做法是偷梁换柱。就是把自己的函数地址替换成待修改函数的内存地址。不过其中涉及到了内存修改、地址偏移量……,具体做法可以参考 TntControls TntSystem.pas 安装系统补丁,或者是 Fastcode 控件包。当然这个替换是会出现副作用的:例如 AQTime 就无法测试安装过 TntSystem 补丁的程序。

3.      直接修改代码的实现
如果是运行库中的具体实现要修改,可以直接动源码,因为改动是implementation 的部分,不会影响到其它的调用该单元的部分。(注意:interface implementation 的内容不能直接修改,否则无法编译通过。)修改之后,勾选编译选项里面的 „Use Debug DCUs“,并编译程序,再将编译得到的 dcu 文件保存到编译目录下面。我一般创建2个目录:PatchedVCLs PreCompiled 放修改过的源码,和编译之后的版本。然后把这个2个目录定义到环境变量里面,这样只要在每个项目的路径设置中添加这些变量,就可以使用改动过的代码了。

4.      间接修改代码的实现
如果要在修改定义部分怎么办?方法3是肯定行不通了。因为所有引用到这个单元的单元也需要重新编译,但不是所有 Delphi 源码你都可以重新编译的。这种情况就伤脑筋了。我目前只可以修改很小一部分的。基本思路是在自己的程序里面定义需访问对象的扩展类和具体实现。然后释放原先对象实例,并以新扩展类重新创建实例。请参考 打入消息循环的另类方法


总结:
以上四种方法是我在修改 Delphi 库或者第三方控件时候所用到的。在修改源码的时候,尽量要考虑到代码的移植性。要做到最少量的修改,得到最好的效果。并且需要考虑修改的代码是否可以在不 同的 Delphi 版本中使用。我在实际项目中,修改了67个源码。(有时间的话,我会一一列出,有需要的可以问我索取。)同时也欢迎交流更多的修改方法,以及 Delphi 不正确封装的补丁。


题外话:

刚刚来自 CodeGear 的消息,Delphi 下个版本会引入了新的技术,直接修改声明部分的代码将变的可能

c++访问私有(private)成员变量的常用方法

类的对象不能直接访问类声明的私有成员变量,否则破坏了信息隐藏的目的。 在C++中,为了防止某些数据成员或成员函数从外部被直接访问,可以将它们声明为private,这样编译器会阻止任何来自外部非友元的...
  • u010418035
  • u010418035
  • 2015年05月04日 20:22
  • 7222

再探私有/公有静态成员变量与私有静态成员方法

问题1: 为什么在类内的静态成员定义后,要到类的外部在定义和初始化? 问题2:为什么类的静态成员在类外部的定义只能一次? 问题3:私有的静态成员变量如何初始化,访问权限还是私有么? 问题4:在程序执行...
  • tianjian789
  • tianjian789
  • 2015年09月06日 12:20
  • 1979

C++中类的访问权限针对的是类而不是对象!(为什么类中的函数可以访问对象的私有成员?)

我们首先看一段程序:class A { private: int i; public: A(int i): i(i) {} void print(A a) { ...
  • fukaibo121
  • fukaibo121
  • 2017年06月22日 21:18
  • 924

C++访问类的私有成员变量的方法(友元函数、友元类)

// win32Test.cpp : Defines the entry point for the console application. // #include "stdafx.h" class...
  • libaineu2004
  • libaineu2004
  • 2014年03月06日 11:28
  • 8847

Python中定义“私有”成员变量和成员函数

参考连接:http://docs.python.org/2/tutorial/classes.html    http://www.pythonclub.org/python-class/privat...
  • doufei_ccst
  • doufei_ccst
  • 2013年06月22日 19:29
  • 14351

对象能够直接访问其私有成员变量

转自:http://www.cnblogs.com/dwdxdy/archive/2012/07/17/2595741.html【C++】 私有成员变量的理解 私有成员变量的概念,在脑海中的...
  • CHENGUANCHI
  • CHENGUANCHI
  • 2014年02月21日 13:49
  • 2395

关于类成员函数中访问同类对象的私有成员

原址:http://wenku.baidu.com/view/4e13d5343968011ca300912c.html (注释: 为了尊重原作者,在不改变内容的前提下,我进行了格式和内容的编辑,...
  • johnnyelf83
  • johnnyelf83
  • 2013年06月22日 16:11
  • 3659

解决“使用google test做单元测试(unit test)中访问类的私有成员”的几种方法

在使用google test做单元测试(unit test)中,有时候会碰到访问类的私有成员, 本文 只给出了两个常用的方法。...
  • wlqingwei
  • wlqingwei
  • 2015年04月10日 17:30
  • 1280

C++访问类中私有成员变量的方法

原则上,C++类中私有变量不允许在类之外的其他任何地方访问,一般来说功能完善的类都会提供get,set方法来操作类属性值,还有就是就是通过友元访问。但是!但如果没有get、set方法都没有提供,也没有...
  • sangni007
  • sangni007
  • 2013年04月08日 17:26
  • 10976

c++静态变量,静态函数,私有静态变量的使用小记

自从上了小学才发现,记忆力大不如前了,看来小的时候没有开发出来,导致记忆模块荒凉遍野,现在很多学过,记过,用过的东西,一段时间以后发现除了有些印象外,再无其他,所以正证明那句话:“好记性不如烂笔头”。...
  • lxp116
  • lxp116
  • 2014年02月20日 11:06
  • 4142
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:如何访问私有成员变量和函数
举报原因:
原因补充:

(最多只允许输入30个字)