我有一些小结构和一个包含它们的大结构:
struct A
{
...
};
struct B
{
...
};
struct AB
{
A a;
B b;
};
在代码的不同位置,我得到一个AB
变量并使用AB.a
和AB.b
执行操作。我想确保如果有人向AB
添加结构,他还会更新使用AB
的代码。
所以我的问题是如何检查?
我知道我不能相信sizeof
并做类似的事情:
sizeof(AB)==sizeof(a)+sizeof(b)
我应该提一下,我并不关心小结构是什么,只有AB
中有多少结构。
有什么建议吗?
谢谢!
编辑:如果我假设A和B只包含基元,那么如果我检查:
offset(last member of B)+sizeof(last member of B)==sizeof(AB)
您怎么看?
答案 0 :(得分:1)
使用C ++,可能的选择是使用模板和Boost.Fusion。
我们使用boost::fusion::vector
作为聚合类:
typename boost::fusion::vector<A,B> Aggregate;
假设我们有一个应该在所有部分上执行的操作:
struct Operation {
void operator()(A& a) { ... } // operation for A
void operator()(B& b) { ... } // operation for B
};
Boost Fusion提供了一个函数,可以对类型容器的所有部分进行简单迭代:
Aggregate x;
boost::fusion::for_each(x, Operation());
如果您现在将聚合扩展到boost::fusion::vector<A,B,C>
,那么当您没有为类型Operation::operator()
提供C
的重载时,您将收到编译器错误。
工作示例:
#include <iostream>
#include <boost/fusion/include/for_each.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/at_c.hpp>
namespace bf = boost::fusion;
struct A { int a; };
struct B { float q; };
typedef bf::vector<A,B> MyClass;
struct IncrementOp {
void operator()(A& x) const { x.a ++; }
void operator()(B& x) const { x.q += 1.0f; }
};
int main() {
MyClass c;
bf::at_c<0>(c).a = 0;
bf::at_c<1>(c).q = 4.2f;
bf::for_each(c, IncrementOp());
std::cout << bf::at_c<0>(c).a << std::endl;
std::cout << bf::at_c<1>(c).q << std::endl;
}
答案 1 :(得分:0)
此不会直接回答您的问题,但说明了如何管理对struct
的更改,而不会因为随着时间的推移添加成员而受到关注。
(注意,这些想法在删除成员时不适用)
使用 struct
构造(过度使用离散类型)的实质性好处正是您所要求的:添加成员的能力不破坏您的代码 struct
类型可以将代码的旧版本与添加其他必需变量的需要隔离开来。也就是说,您可以将成员添加到全局定义的结构中,而不必强制更改包含在其参数列表中的任何函数的原型。
例如 :给出具有以下结构的方案:
(注意,我使用的是typedef
,因此参数列表中的声明会更短,并添加了真实成员)
此处 是您的原始方案:
typedef struct
{
int a1;
int a2;
}A;
typedef struct
{
int b1;
int b2;
}B;
typedef struct //small change for less text in prototypes
{
A a;
B b;
}AB;
这里 是两个使用struct AB的函数
这个是在对原始AB进行任何修改之前编写的(目前不需要新成员)
void func1(AB var_old)
{
var_old.a.a1 = 3;
var_old.a.a2 = 3;
var_old.b.b1 = 4;
var_old.b.b2 = 4;
//Note: if var_old.b.b3 is ever needed here, it is available without changing prototype
}
稍后 创建(或修改)需要新变量的函数
将成员添加到结构B:
typedef struct
{
int b1;
int b2;
int b3;
}B;
在此处使用:
void func2(AB var_new)
{
var_new.a.a2 = 10;//pre-existing member
var_new.b.b3 = 4; //new member
}
原型参数列表没有改变,因此无需编辑使用AB
的每个函数。
答案 2 :(得分:0)
我找到并正在使用的解决方案是以下检查:
if !(sizeof(A+B) + 3 >= sizeof(AB)){
return error;
}
我有一些放松假设,这使得这个条件成为我问题的解决方案:
B
)都足够大,并且包含一个size>=4
的成员 - 这可以确保4个结构的大结构AB
仅包含结构在这种情况下,如果有人在不更改此条件的情况下添加AB
第三个结构C
,他就会收到错误(即使sizeof(c)<3
因为{{1}}对齐)。这正是我想要的。