我有一个结构供别人使用,他们也依赖sizeof(struct S)
。下面是我的结构,
struct S{
int aVar1;
void *ptr1;
}
将来,我可能会添加新成员(现在不确定),比如..
struct S{
int aVar1;
void *ptr1;
int aVar2;
void *ptr2;
}
我知道这会破坏与依赖sizeof
的用户的向后兼容性。
为了避免这种情况,我计划在struct中添加一些可以在将来使用的虚拟指针。
struct S{
int aVar1;
void *ptr1;
void *dummyptr1;
void *dummyptr2;
void *dummyptr3;
void *dummyptr4;
void *dummyptr5;
void *dummyptr6;
}
任何更好的解决方案请保持向后兼容性?
答案 0 :(得分:5)
不要这样做。
将新成员添加到结构中是不安全的,希望现有的成员保持其当前的填充安排。 C和C ++标准都没有在这方面做出任何保证。
唯一安全的方法是从头开始构建新结构并添加新的API函数。
答案 1 :(得分:2)
Afaik,C方式是使用扩展,如下:
struct A{
int data;
void* extension;
};
然后,在需要时添加扩展名并使用扩展指针将其与原始A
链接。
struct A_ext1{
int ext_data;
void* extension;
};
A a;
A_ext1 a_ext1;
a.extension = &a_ext1;
依此类推...这将创建一个讨厌的“分层”结构结构。这可确保您的原始结构永远不会更改,因此使用旧接口的客户端在更改后将保持兼容,而无需重新编译。
这里重要的是跟踪您的界面版本 - 每个新扩展名都是新版本。十个客户需要了解他们支持的版本,因此他们只知道并支持扩展,直到他们知道的版本。此外,您需要确保不将此类结构的所有权传递给客户端。他们不知道可能有多少层扩展,所以他们无法正确销毁整个事物。
当然你也可以尝试使用C ++方法,只使用继承,创建从旧版本继承的新版本的struct。我不确定后一种方法的含义,但它也应该有用。
答案 2 :(得分:1)
如果它是c ++,你可以编写一个从旧结构派生的新结构。通过这样做,您可以在旧函数中使用新结构,并为新结构提供新功能。
答案 3 :(得分:1)
使用"装饰器模式"专门解决了这个问题。它只是允许您使用组合扩展现有类(在您的情况下为结构)的功能而不更改其结构。您只需创建一个新结构(或类),将旧结构作为新结构中的成员。然后,您可以根据需要为此新结构添加新功能。更多信息here。