使用公共成员变量的地址访问私人成员

Using the address of a public member variable to access a private member

本文关键字:成员 地址 访问 变量      更新时间:2023-10-16

我创建了以下简单的测试程序,以表明我可以使用公共整数的地址访问私人整数的值:

#include <iostream>
using namespace std;
class CarType{
  public:
    int year;
    CarType(int price, int year){this -> year = year; this -> price = price;};
  private: 
    int price;
};
int main(){
  //Create new CarType object
  CarType a = CarType(15000, 1999);
  //Increment the memory address of public member variable, year by 1 and save the result
  int* pricePointer = &a.year+1;
  //De-reference the memory address and output it
  cout << "PRICE: "<< *pricePointer << endl;
  return 0;
}

输出表明我只能通过了解年度地址就可以访问价格变量。有没有办法防止这种情况?这只是一个边缘情况还是所有类型的对象?

是正确的

这可能是可能是 不确定的(但肯定是不明智的)行为,您可以以完全相同的方式阻止人们写入随机地址或防止经验不足的人通过用电锯切断四肢。换句话说,根本不是。

警告编码器。

我说可能的原因是,这并不完全清楚。用语言律师术语,请参阅C++14 5.7 Additive operators /4

出于这些运算符的目的,指向非阵列对象的指针与指向长度为"元素类型"元素的第一个元素的指针相同。

/5讨论向指针添加积分值时:

如果指针操作数和结果指向同一数组对象的元素,或一个超过数组对象的最后一个元素,则评估不会产生溢出;否则,行为是不确定的。

在您的情况下,您的指针实际上指着"一个超过最后一个元素",因此添加本身不会产生未定义的行为。

您可能会认为对对象的删除将是不确定的,但是根据3.9.2 Compound types /3中的注释,它似乎是有效的:

例如,将考虑一个超过数组(5.7)末端的地址指向可能位于该地址的数组元素类型的无关对象。

但是,无论是否未定义,取消率仍然是不明智的,因为您实际上不知道在那里有一个正确的类型的变量。实施是免费的,因为他们认为合适,因此无法保证price*(year + 1)相同。