私人成员黑客定义的行为?

ere*_*eOn 22 c++ casting private-members

我有以下课程:

class BritneySpears
{
  public:

    int getValue() { return m_value; };

  private:

    int m_value;
};
Run Code Online (Sandbox Code Playgroud)

哪个是外部库(我无法更改).我显然无法改变它的价值m_value,只能读它.即使是衍生BritneySpears也行不通.

如果我定义以下类,该怎么办:

class AshtonKutcher
{
  public:

    int getValue() { return m_value; };

  public:

    int m_value;
};
Run Code Online (Sandbox Code Playgroud)

然后做:

BritneySpears b;

// Here comes the ugly hack
AshtonKutcher* a = reinterpret_cast<AshtonKutcher*>(&b);
a->m_value = 17;

// Print out the value
std::cout << b.getValue() << std::endl;
Run Code Online (Sandbox Code Playgroud)

我知道这是不好的做法.但出于好奇:这是否有效?它是否定义了行为?

奖金问题:你有没有必要使用这样一个丑陋的黑客?

编辑:只是为了吓唬更少的人:我不打算在实际代码中实际执行此操作.我是在想 ;)

Mar*_*tos 21

这是未定义的行为.每个访问限定符部分中的成员都保证按其出现的顺序排列,但是在acccess限定符之间没有这样的保证.例如,如果编译器选择将所有私有成员放在所有公共成员之前,则上述两个类将具有不同的布局.

编辑:重新回答这个旧答案,我意识到我错过了一个相当明显的观点:结构定义每个都只有一个数据成员.成员函数的顺序无关紧要,因为它们不会影响类的布局.您可能会发现,这两个数据成员保证是在同一个地方,虽然我不知道标准不够好肯定地说.

但!您无法取消引用reinterpret_cast不相关类型之间的结果.它仍然是UB.至少,这是我对http://en.cppreference.com/w/cpp/language/reinterpret_cast的阅读,这确实是一个粗略的阅读.

  • @ereOn对于这样的事情,唯一可以确定的方法是阅读并理解标准. (2认同)

Mic*_*fik 9

由于Marcelo指出的原因,这是未定义的行为.但有时你需要在集成无法修改的外部代码时采用这些方法.一种更简单的方法(以及同样未定义的行为)是:

#define private public
#include "BritneySpears.h"
Run Code Online (Sandbox Code Playgroud)

  • 我们可以让私人会员没有"私人"标签,所以这可能不起作用;) (5认同)
  • @Nick:`#define class struct`.不是说我会做那样的事情. (3认同)