13

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

4

2 回答 2

18

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

例如,在我的带有 GCC 4.6 的 Linux/x86-64 上,下面的程序完全按照您的期望打印。它绝不是可移植的,并且可能会在异国情调的编译器上打印出意想不到的东西,但即使是那些编译器也会有自己特定的方式来获取私有成员。

#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;
}

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

于 2012-07-14T19:12:02.607 回答
3

编译器的工作是查看某些成员是私有的并禁止您使用它们。他们不是任何编译后与其他成员有很大不同。

然而,有一个重要的方面,数据成员不需要按照它们在类定义中出现的顺序排列在内存中,但是对于具有相同访问级别的变量,它们是必需的。

于 2012-07-14T19:15:58.170 回答