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的阅读,这确实是一个粗略的阅读.
由于Marcelo指出的原因,这是未定义的行为.但有时你需要在集成无法修改的外部代码时采用这些方法.一种更简单的方法(以及同样未定义的行为)是:
#define private public
#include "BritneySpears.h"
Run Code Online (Sandbox Code Playgroud)