添加新成员到C ++结构和向后兼容性

时间:2017-07-11 09:11:33

标签: c++ c backwards-compatibility

我有一个结构供别人使用,他们也依赖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;
 }

任何更好的解决方案请保持向后兼容性?

4 个答案:

答案 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