我创建了以下简单的测试程序,以表明我可以使用公共整数的地址来访问私有整数的值:
#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;
}
输出显示我只需知道年份的地址即可访问价格变量。有没有办法防止这种情况发生?这只是一个边缘情况还是适用于所有类型的对象?
答案 0 :(得分:3)
这可能是可能未定义(但肯定是不明智的)行为,你可以像防止人们写入随机地址一样阻止它,或者防止没有经验的人用链锯切断四肢。换句话说,根本不是。
Caveat Coder。
我在上一段中说可能的原因是它并不完全清楚。在语言 - 律师术语中,请参阅C++14 5.7 Additive operators /4
:
在讨论向指针添加整数值时出于这些运算符的目的,指向非阵列对象的指针与指向长度为1的数组的第一个元素的指针的行为相同,其中对象的类型为其元素类型。
和/5
:
如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出;否则,行为未定义。
在你的情况下,你的指针实际指向&#34;一个指过最后一个元素&#34;因此,添加本身不会产生未定义的行为。
您可能认为取消引用该对象是未定义的,但根据3.9.2 Compound types /3
中的注释,它似乎有效:
例如,超过数组末尾的地址(5.7)将被视为指向可能位于该地址的数组元素类型的无关对象。
但是,未定义或未定义,取消引用仍然不明智,因为您实际上知道那里存在正确类型的变量。实现可以根据需要自由填充结构,因此无法保证price
与*(year + 1)
相同。