如何在C++中实现私有变量的访问?

Sha*_*dra 13 c++ memory-management data-protection private-members

编译器如何控制内存中变量的保护?是否有与内存中的私有变量相关联的标记位?它是如何工作的?

Fre*_*Foo 18

如果您的意思private是实例的成员,那么在运行时没有任何保护.所有保护都在编译时进行,如果你知道它们在内存中的布局,你总是可以得到一个类的私有成员.这需要平台和编译器的知识,在某些情况下甚至可能依赖于编译器设置,例如优化级别.

例如,在我的Linux/x86-64 w/GCC 4.6上,以下程序打印出您期望的内容.它绝不是可移植的,可能会在异国情调的编译器上打印出意想不到的东西,但即使是那些编译器也会有自己特定的方式来访问私有成员.

#include <iostream>

class FourChars {
  private:
    char a, b, c, d;

  public:
    FourChars(char a_, char b_, char c_, char d_)
      : a(a_), b(b_), c(c_), d(d_)
    {
    }
};

int main()
{
    FourChars fc('h', 'a', 'c', 'k');

    char const *p = static_cast<char const *>(static_cast<const void *>(&fc));

    std::cout << p[0] << p[1] << p[2] << p[3] << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

(复杂的强制转换是存在的,因为void*它是唯一可以强制转换为任何指针的类型.void*然后可以在char*不调用严格别名规则的情况下强制转换.也许可以使用单个reinterpret_cast- 在实践中,我从不玩这个一种肮脏的技巧,所以我不太熟悉如何以最快的方式做到这一点:)

  • 标准草案N3242 9.2.20指向标准布局结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然.[注意:因此,在标准布局结构对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐.结束说明] (3认同)