严格说,C++的禁止外部类访问private 是指在编译期,运行期都是在内存中的数据,是可以做任何修改的。本文的方式讲的就是针对运行期如何修改。
这个方案源于N年前有个第三方实现的静态库,我们没有代码,只有库的头文件声明和编译好的lib库。在一个类的头文件中,有个私有变量存储的是Color值,但库的开放接口却没有能力修改这个值。
### 方法
通过头文件的类定义,算出该私有变量在内存中的偏移值,有了偏移值,就可以通过获取该类实例在内存中的地址,从而算出私有变量的内存地址。需要对class内存结构有所了解,如图:
![class struct](http://p.blog.csdn.net/images/p_blog_csdn_net/pathuang68/EntryImages/20090424/1604.GIF)
具体实现代码:
~~~.cpp
// 获取开始内存地址
volatile char *pThis = (char *)&pRichEditChatLogEx;
volatile CHARFORMAT2 cf;
ZeroMemory((char *)&cf, sizeof(CHARFORMAT2));
cf.cbSize = sizeof(CHARFORMAT2);
cf.crTextColor = RGB(0, 0, 0);
cf.yHeight = 20 * 10;
cf.dwMask = CFM_COLOR | CFM_FACE | CFM_SIZE | CFM_PROTECTED;
cf.dwEffects = 0;
cf.bCharSet = 134;
cf.bPitchAndFamily = 34;
// 算偏移地址,篇幅原因,不贴出具体类的定义了
// 下面的公式是取基类最后结束的偏移,仔细想想,是从屁股开始往前推...
int endOffset = sizeof(CRichEditChatLogEx) * 2 - sizeof(CRichEditChatLog);
// 通过调试内存看出,DEBUG下,内存多4个字节
#if _DEBUG
volatile int offset = endOffset - sizeof(CHARFORMAT2) - 20;
#else
volatile int offset = endOffset - sizeof(CHARFORMAT2) - 24;
#endif
// 内存写入要修改的值,注意千万不要超出数据长度哦,否则就是场灾难
memcpy((char *)&pThis[offset], (char *)&cf, sizeof(CHARFORMAT2));
~~~
转自:http://www.yinqisen.cn/blog-530.html
分享到:
相关推荐
根据提供的代码示例和描述,我们可以深入探讨C++中如何强制访问类的私有成员以及相关的技术细节。这里的关键在于理解C++中的内存布局、类型转换以及预处理器指令的使用。 ### C++中的内存布局 在C++中,类的成员...
c++访问私有private成员变量的常用方法 在 C++ 编程中,private 成员变量是类的内部实现细节,不能被外部直接访问,这是为了保护类的封装性和安全性。然而,在某些情况下,我们需要访问私有成员变量,例如在测试、...
除了`public`之外,C++还支持`private`和`protected`两种访问控制属性。 #### 创建对象并操作成员变量 定义完类之后,我们可以通过创建类的对象来使用成员变量。对象是类的一个实例,它拥有类所定义的所有成员变量...
友元函数可以访问类的 private 和 protected 成员,无论它们是否是类的成员。友元函数可以是全局函数,也可以是另一个类的成员函数。友元关系不被继承,即子类的友元不是基类的友元。 7. **类的内存布局**: 每个...
在C++中,静态成员函数可以被类的所有对象共享,它并不持有隐含的`this`指针,因此不能访问非静态成员变量。静态成员函数通常用于执行与对象状态无关的操作,如计算、比较等。例如,在`静态成员函数.cpp`中,可能会...
静态数据成员遵守public/protected/private访问规则,并具有以下特点: 1. 静态数据成员的定义:静态数据成员主要用在各个对象都有相同的某项属性的时候,静态数据成员实际上是类域中的全局变量。因此,静态数据...
C++ 类访问控制机制是面向对象编程中的核心概念,它主要涉及到`public`、`private`和`protected`这三个访问修饰符。它们的作用是限制类的成员(数据成员和成员函数)在不同作用域内的可访问性,从而实现数据封装和...
`public`成员可以在类的任何地方被访问,`private`成员只能在类的内部访问,而`protected`成员则可以被类本身及其派生类访问。 3. **成员变量的私有化**:将成员变量声明为`private`,意味着它们不能直接从类的外部...
同时,静态成员还支持访问控制,可以设置为private,限制对其的直接访问。 总结来说,C++的类静态成员提供了一种管理全局数据的有效方法,它可以避免全局变量带来的许多问题,同时提供了更好的封装和控制。在设计...
C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++C++
静态数据成员是类中的全局变量,它们遵守public、protected和private访问规则。静态数据成员的定义需要在cpp文件中进行,而不能在头文件中进行。例如: xxx.h文件: class base{ private: static const int _i; };...
它既可以在`B`的上下文中被调用,也可以访问`A`的私有成员`private_data`。这样的设计可能是因为`B`需要在特定情况下修改`A`的内部状态,而这是其他非友元函数无法做到的。 需要注意的是,友元成员函数虽然强大,但...
这种设计允许类A访问类B的成员,同时类B也可以访问类A的成员,形成一种循环依赖的关系。然而,这种关系需要谨慎处理,以避免编译错误和设计上的问题。下面我们将深入探讨这个主题。 首先,我们要理解C++中的“包含...
在C++中,数据成员的访问权限可以通过关键字public、private和protected来控制。公共成员(public)对所有代码可见,可以直接访问;私有成员(private)只能在类的内部访问,对外部代码隐藏,实现了数据封装;保护...
在C++中,类的成员可以被声明为私有的(private),这意味着它们在类的外部不能直接访问。这是封装性原则的体现,有助于保护数据的安全性和完整性。然而,在某些情况下,我们需要在类外部修改私有成员,这通常通过...
public成员可以被类外的任何代码访问,protected成员可以被类内和友元访问,private成员只能被类内和友元访问。 现在,让我们深入了解三种继承方式的特点: 1. public继承 在public继承中,基类的public成员、...
- 友元函数(Friend functions)是非成员函数,但可以访问类的private和protected成员。声明一个函数为友元,可以打破封装原则,允许该函数直接访问类的私有和保护成员。 - 友元类(Friend classes)是整个类而...
在成员变量和成员函数的访问方面,C++提供了多种机制,包括public、protected 和 private 三种访问权限。成员函数可以访问类的成员变量,包括私有成员变量。虚函数调用也是一个复杂的机制,它需要通过虚函数表来实现...
7. **指针成员的访问控制**:合理设置指针成员的访问权限(public, protected, private)对于保证数据封装和类的正确使用至关重要。通常,将指针成员设为private,然后通过public的成员函数来访问和修改它们。 8. *...