改变班级的私人成员

时间:2017-02-28 06:24:19

标签: c++ visual-c++

访问和更改私有类成员的值:

#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。

此行为是否未定义和/或编译器相关?

UPDATE :StackOverflow会为您提供积分吗?

2 个答案:

答案 0 :(得分:4)

  

此行为是否未定义和/或编译器相关?

使用int*访问类型为size_t的变量是不好的,无论变量是在类中还是单独存在。

如果您使用

*(reinterpret_cast<size_t*>(h)) = 100;

它不是未定义的行为,它不依赖于编译器。我怀疑,如果你使用它将没有任何不同:

*((size_t*)h) = 100;

您的课程符合标准布局 struct的要求。

来自C ++ 11标准:

  

9个课程

     

...

     

7标准布局类是一个类:

     

- 没有非标准布局类(或此类类型的数组)或引用类型的非静态数据成员,

     

- 没有虚函数(10.3),没有虚基类(10.1),

     

- 对所有非静态数据成员具有相同的访问控制(第11条),

     

- 没有非标准布局基类,

     

- 要么在大多数派生类中没有非静态数据成员,要么最多只有一个具有非静态数据成员的基类,或者没有带有非静态数据成员的基类,并且

     

- 没有与第一个非静态数据成员相同类型的基类。

     

8 标准布局结构是使用类 - 键 struct类 - 键定义的标准布局类em> class

对于标准布局 struct,指向对象的指针可以别名为指向第一个成员变量的指针。

来自C ++ 11标准:

  

9.2班级成员

     

...

     

20指向标准布局结构对象的指针(适当地使用reinterpret_cast转换)指向其初始成员(或者如果该成员是位字段,则指向它所在的单位)和反之亦然。 [注意:   因此,在标准布局结构对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐。 - 结束记录]

答案 1 :(得分:1)

在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;并且可能正常(请参阅其他答案)。