标准布局类的偏移量?

时间:2013-11-24 03:00:41

标签: c++ c++11

#include <iostream>
#include <cstddef>
class Foo
{
    int a;
    int b;
    float c;
};
int main()
{
    Foo foo;
    std::cout << offsetof(Foo, b) << std::endl;
    return 0;
}

上面的代码无法使用gcc-4.8.2或vc ++ 11进行编译。错误消息无法访问类Foo中的私有成员b。

但是根据标准,offsetof应该支持标准布局类,而Foo是标准布局类。

这是gcc-4.8.2还是vc ++ 11的缺陷,或者我对c ++标准的理解是错误的?

3 个答案:

答案 0 :(得分:1)

默认情况下,班级中的数据成员是私有的。只有在公开下声明它们才能从main访问它们。或者你可以通过在公共下声明类中的函数并从main调用它来从main访问它们。由于类中的函数可以访问类中的数据成员,因此可以访问私有数据成员。

答案 1 :(得分:1)

offsetof 被定义为,因此它无法绕过访问控制并获得对私有成员的访问权限,我们可以看到这是通过草拟C ++标准部分17.6.1.2 标题段落 5 来表达(强调我的):

  

在C 中定义为宏的名称应在C ++标准库中定义为宏,即使C授予实现许可作为函数。 [注意:在C中定义为宏的名称包括以下内容:assert, offsetof ,setjmp,va_arg,va_end和va_start。 - 后注]

更新

所以有些hacks可以让你以标准的方式访问类的私有成员但是如果我们回到C99草案标准,草案C ++标准依次为 offsetof 然后我们在第7.17部分通用定义 3 中看到(强调我的):

   offsetof(type, member-designator)
  

扩展为一个整数常量表达式,其类型为size_t,值为   这是结构成员的偏移量(以字节为单位)(由mem​​ber-designator指定),   从其结构的开头(按类型指定)。类型和成员指示符   应该是

   static type t;
  

然后表达式&amp;(t.member-designator)评估为地址常量

如果您尝试从班级外部访问私人会员,情况就不会如此。

答案 2 :(得分:0)

类成员默认为private。 将它们列为公共,或使Foo成为结构(因为结构成员默认为公共),并且上述工作,否则主要不允许访问b,而offsetof被视为访问。