C ++中的Access Specifier

时间:2011-02-03 08:02:09

标签: c++

我阅读了BRUCE ECKEL在C ++中思考的以下陈述

  

1.访问说明符是结构的一部分,不影响对象
  从“结构

创建

怀疑:我们知道访问块不是连续存储的, 不知道访问说明符会改变内存中对象布局的方式

  

2.所有访问规范信息在程序运行之前消失   (在编译期间)。在正在运行的程序中,对象成为“存储区域”
  而且没有更多..我们可以打破所有规则并直接访问内存   你可以在c

怀疑:这是否意味着甚至可以直接访问私人会员?请帮助我理解上述陈述

  

3.c ++设计是务实的,而不是渴望抽象交易

怀疑:什么是务实的意思?

2 个答案:

答案 0 :(得分:8)

  

1)访问说明符是结构的一部分,不影响从“结构”

创建的对象

实际上,在相同的特定访问权限(publicprotectedprivate)内的数据成员的顺序(在布局中)取决于他们在代码中的顺序,但是没有为具有不同说明符的数据成员指定顺序。

class Foo
{
public:
  int a;
  int b;
protected:
  int c;
  int d;
};

我们唯一知道的是a必须在bc必须在d之前到来。 abcdacbdacdbcabdcadbcdab都是可能的。

  

2)所有访问规范信息在程序运行之前消失   (在编译期间)。在正在运行的程序中,对象成为“存储区域”   而且没有更多..因此我们可以打破所有规则并直接访问内存   你可以在c

该信息仅在编译期间使用,但编译是生成运行代码的原因。因此,编译可确保您不会访问private成员。但是,由于允许直接内存操作,如果您愿意,可以有效地访问private成员或函数,尝试手动执行此操作非常容易出错。

  

3)C ++旨在务实,而不是渴望抽象真实的

务实意味着它面向实际使用,很少考虑纯粹的理论论证。从CS理论构建的语言将包括例如Haskell,其具有极其合理的数学背景;另一方面,C ++积累了一些被用户认为有用的功能。

此外,C ++不会隐藏您的低级细节(如内存管理)。好的C ++代码通常会让编程器使用习惯用法来尝试抽象它(有点),但如果有必要,你可以随时更接近金属(甚至直接包括汇编代码)......有时候(比如内存管理)你必须要注意你正在做的事情。

答案 1 :(得分:1)

class Foo {
    int x, y;
  public:
    int z;
    Foo(int a, int b) : x(a), y(b) {}
};
Foo foo;

您可以非常轻松地访问私有成员变量:

memset(&foo, int 0, sizeof(foo));  // wipes them all
fwrite(&foo, sizeof(foo), 1, fp);  // dumps them to stream fp

正如一些评论者指出的那样,这引发了C ++标准下的未定义行为,所以在尝试之前要知道你的编译器(或者更好,不要)。如果您知道编译器如何打包类,您甚至可以通过诸如

之类的黑客获得更细粒度的访问
struct PublicFoo {
    int x, y, z;    // order, padding, etc. depends on compiler
};

并将Foo *投射到PublicFoo *。 C ++运行时中没有任何内容可以阻止它。