【问题标题】:Struct attribute inheritance in c++c++中的结构属性继承
【发布时间】:2012-09-21 12:52:58
【问题描述】:

结构的属性是在 C++ 中继承的

例如:

struct A {
    int a;
    int b;
}__attribute__((__packed__));

struct B : A {
    list<int> l;
};

struct B(struct A)的继承部分会继承packed属性吗?

如果没有收到编译器警告,我无法将 attribute((packed)) 添加到结构 B:

ignoring packed attribute because of unpacked non-POD field

所以我知道整个 struct B 不会被打包,这在我的用例中很好,但我需要将 struct A 的字段打包到 struct B 中。

【问题讨论】:

  • 你确定A中需要这个属性,还是A只是一个例子?

标签: c++


【解决方案1】:

是的,A 的成员将被打包在struct B 中。必须是这样,否则会破坏整个继承点。例如:

std::vector<A*> va;
A a;
B b;
va.push_back(&a);
vb.push_back(&b);

// loop through va and operate on the elements. All elements must have the same type and behave like pointers to A.

【讨论】:

  • 苦苦尝试,看了看汇编,突然想到了继承的情况……Brainfart。
【解决方案2】:

struct B(struct A)的继承部分会继承packed属性吗?

是的。继承的部分仍将被打包。但是pack属性本身并没有被继承:

#include <stdio.h>

#include <list>
using std::list;

struct A {
    char a;
    unsigned short b;
}__attribute__((__packed__));

struct B : A {
    unsigned short d;
};

struct C : A {
    unsigned short d;
}__attribute__((__packed__));

int main() {
   printf("sizeof(B): %lu\n", sizeof(B));
   printf("sizeof(C): %lu\n", sizeof(C));

   return 0;
}

当调用时,我得到

sizeof(B): 6
sizeof(C): 5

我认为您的警告来自非 POD 类型且本身未打包的列表 成员。另见What are POD types in C++?

【讨论】:

  • @Andreas - 你就像 Didier 说的,我不能打包 struct B 因为我有一个列表变量。感谢您的建议,但 struct B 和 C 之间的大小差异可能是因为变量 'd'。我想知道结构 B 中的变量 'a' 和 'b' 是否被打包,并且总是会被打包
  • 是的 - 只需根据其他一些答案重新阅读您的问题 - 所以,是的,inherited part 仍然是打包的,但打包的属性本身没有被继承。如果需要,您需要在子结构中重新表述它,这仅在其中没有非 POD 对象时才有效。
  • @squater:您可以编写一个测试用例检查“struct B”中“b”成员的偏移量,并检查它是否在预期位置。但是,C++ 子类/结构不支持用于执行此检查的 offsetof 宏,另请参见 What is wrong with this use of offsetof?。所以,这个问题可能更像是“如何确保成员在预期的偏移量处对齐”。
猜你喜欢
  • 2020-01-19
  • 1970-01-01
  • 2022-07-27
  • 1970-01-01
  • 2017-12-18
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 2015-12-12
相关资源
最近更新 更多