为什么我们必须在对象地址前面提到数据类型才能访问C ++中类的私有成员?

c++ class oop pointers private

64 观看

3回复

11 作者的声誉

我正在尝试通过指针访问私有成员。我想知道为什么我们在(int *)&t前面提到dtype?

class Test
{
private:
    int data;
public:
    Test() { data = 0; }
    int getData() { return data; }
};

int main()
{
    Test t;
    int* ptr = (int*)&t;
    *ptr = 10;
    cout << t.getData();
    return 0;
}
作者: rida 的来源 发布者: 2017 年 9 月 15 日

回应 3


0

3800 作者的声誉

(int*)&t :将指针强制转换为整数指针

int* ptr = (int*)&t; :它将t的指针存储在ptr中

作者: iamsankalp89 发布者: 2017 年 9 月 15 日

3

109656 作者的声誉

访问控制系统适用于名称。这是data私有名称,而不是任何变量或关联的存储区域。换句话说,只要不使用名称data即可使用其他方式访问变量。

访问控制的目的是防止代码意外破坏封装

有时有人说C ++“给了您足够的绳索来吊死自己”,或“防止Murphy却没有Macchiavelli的保护”,换句话说,如果您确实愿意,可以绕过访问控制。链接到相关文章-GotW#76

当然,您应该尝试以不需要旁路访问控制的方式来设计代码。


在这种特殊情况下,代码定义明确。由于Test标准布局类,因此可以确保在第一个数据成员之前没有填充,并且还可以确保此强制转换产生t.data可用于访问所述变量的指针。

对于更复杂的类,如果有问题的数据成员不在对象存储空间的开头,则您的代码可能无法工作。

作者: M.M 发布者: 2017 年 9 月 15 日

0

3417 作者的声誉

首先它只是偶然的。

Test 是一个不涉及继承,没有虚拟方法,未经RTTI支持而编译的原始类,或任何其他可能导致内存中表示形式膨胀的类。

在这个简单的示例中,唯一的成员变量与整个对象位于同一地址。依靠它是极其不安全的,因为对于任何更复杂的事物,它都是不确定的行为。

尝试例如现在将继承和虚拟方法引入您的测试中。突然,对象的前几个字节不再是第一个成员变量(这是编译器通常放置VPTR的位置),并且您测试的崩溃非常糟糕。

或将成员变量设置为静态变量,现在对象本身实际上是空的,而是访问堆控制结构,这不一定会立即导致崩溃,但堆损坏会更加严重。好吧,在这种情况下t是堆栈分配的,所以您只能破坏堆栈(这要差一点点),但是如果是堆栈分配,这将变得很关键。

作者: Ext3h 发布者: 2017 年 9 月 15 日
32x32