繁体   English   中英

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

[英]Why we have to mention data type in front of address of the object to access the private members of a class in C++?

我正在尝试通过指针访问私有成员。 我想知道为什么我们在(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;
}

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

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

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

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


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

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

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

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

首先它只是偶然的。

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM