[英]Change private member of class
访问和更改私人班级成员的价值:
#include <stdio.h>
class hack_Me
{
private:
size_t age;
public:
size_t getAge() const
{
return this->age;
}
explicit hack_Me(size_t age):age(age) { }
};
void change_age(hack_Me* h)
{
*((int*)h) = 100;
}
int main(int argc, char* argv[])
{
hack_Me h(12);
printf("%d \n", h.getAge());
change_age(&h);
printf("%d \n", h.getAge());
getchar();
return 0;
}
12点后打印100。
它适用于MSVC 14。
此行为是否未定义和/或依赖于编译器?
更新 :StackOverflow会给你点赞吗?
此行为是否未定义和/或依赖于编译器?
使用int*
访问size_t
类型的变量是不好的,无论该变量是在类内部还是本身。
如果您使用
*(reinterpret_cast<size_t*>(h)) = 100;
这不是未定义的行为,也不依赖于编译器。 我怀疑,使用以下内容不会有什么不同:
*((size_t*)h) = 100;
您的课程符合标准布局 struct
的要求。
从C ++ 11标准:
9节课
...
7标准布局类是这样的类:
—没有非标准布局类(或此类数组)或引用的非静态数据成员,
—没有虚拟函数(10.3)和虚拟基类(10.1),
—对所有非静态数据成员具有相同的访问控制(条款11),
-没有非标准布局的基类,
—在派生最多的类中没有非静态数据成员,并且在最多一个具有非静态数据成员的基类中,或者没有具有非静态数据成员的基类,并且
—没有与第一个非静态数据成员相同类型的基类。
8 标准布局结构是用class-key
struct
或class-keyclass
定义的标准布局class
。
对于标准布局 struct
,对象的指针可以别名为第一个成员变量的指针。
从C ++ 11标准:
9.2班级成员
...
20指向标准布局结构对象的指针(使用
reinterpret_cast
进行了适当转换)指向其初始成员(如果该成员是位域,则指向其驻留的单元),反之亦然。 [注意:因此,在标准布局结构对象中可能会存在未命名的填充,但在其开始时可能没有,这是实现适当对齐所必需的。 — 尾注 ]
在hack_Me内部,您有size_t age;
可能小于int(例如,在8位体系结构下,sizeof(size_t)== 1和sizeof(int)== 2)。 如果您的编译器在hack_Me的末尾没有生成填充,则可能会发生整个hack_Me小于int的情况,因此*((int*)h) = 100;
可能会覆盖比仅hack_Me的第一个成员更多的内存。 将hack更改为*((size_t*)h) = 100;
可能还可以(请参阅其他答案)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.