针对同一接口的多个版本的C ++设计(头文件中的枚举/结构) [英] C++ design for multiple versions of same interface (enumerations / structures in header files)

查看:35
本文介绍了针对同一接口的多个版本的C ++设计(头文件中的枚举/结构)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在与一个外部控制的程序交互,该程序具有定义的包含枚举和结构的标头.我们希望能够以尽可能少的重复代码与该程序的多个版本进行交互.每个版本都有相同的一般枚举和结构,但随着时间的推移会稍作修改.在理想的设置中,我们可以有条件地包含同一标头的不同版本(即,如果与版本1接口#include"version1 \ progDefs.h",否则#include"version2 \ progDefs.h"),但不要相信这在C ++中是可能的.

We are interfacing with an externally controlled program with defined headers containing enumerations, and structures. We want to be able to interface with multiple versions of this program with as little duplication of code as possible. Each version has the same general enums and structures, but with slight modifications over time. In the ideal setup we could just conditionally include the different versions of the same header (i.e. if interfacing with version 1 #include "version1\progDefs.h", else #include "version2\progDefs.h"), but don't believe that is possible in C++.

下面是一个简单的示例,用于说明问题和我们当前正在做的事情.谢谢您的协助.

Below is a simple example to illustrate the issue and what we are currently doing. Thank you for any assistance.

version1 \ progDefs.h包含

version1\progDefs.h contains

enum items
{  
  BOOK_TYPE = 0,
  PAGE_TYPE = 1,
  WORD_TYPE = 2
};
struct packet
{
  int type;
};

version2 \ progDefs.h包含

version2\progDefs.h contains

enum items
{  
  VOLUME_TYPE = 0,
  BOOK_TYPE = 1,
  PAGE_TYPE = 2,
  WORD_TYPE = 3
};
struct packet
{
  int type;
  char detail[80];
};

我们现在希望将数据包结构写到网络上,从而能够在运行时选择要使用的版本.当前,我们为每个版本提供一个基类,然后一个子类.他们看起来像这样

We now want to write out the packet structure to the network, being able to pick at runtime which version to use. Currently we have a base class and then one child class for each version. They look something like this

baseWriter.h

baseWriter.h

class baseWriter
{
    virtual void sendBookPacket() = 0;
};

version1Writer.cpp

version1Writer.cpp

#include "baseWriter.h"
#include "version1\progDefs.h"

class version1Writer : public baseWriter {};
void version1Writer::sendBookPacket()
{
  struct packet pkt;
  pkt.type = BOOK_TYPE;
  sendNetworkPacket((void*)&pkt, sizeof(pkt));
}

version2Writer.cpp

version2Writer.cpp

#include "baseWriter.h"
#include "version2\progDefs.h"

class version2Writer : public baseWriter {};
void version2Writer::sendBookPacket()
{
  struct packet pkt;
  pkt.type = BOOK_TYPE;
  sendNetworkPacket((void*)&pkt, sizeof(pkt));
}

这将起作用,但是如您所见,这两个类中的代码完全相同.唯一的区别是所使用的值和结构不同,因为标头的版本不同.实际上,该项目有许多包含数百个项目的枚举和许多结构,而我们无法控制这些结构.它们可以随时更改,但是我们的代码不需要更改,因为新元素与程序无关.但是,更改确实会影响所使用元素的值/大小.有没有什么方法可以设计我们的代码以使用这些标头而不重复代码?谢谢!

This will work, but as you can see the code is the exact same in both classes. The only difference is in the values and structure used because of the different version of headers. In reality the project has many enumerations with hundreds of items, and many structures, none of which we have control over. They can change at any time, but our code doesn't need to as the new elements are not relevant to the program. However the changes do effect the values / size of the elements used. Is there any way to design our code to use these headers without duplicating code? Thank you!

注意:我们不支持C ++ 11.感谢您的建议.许多建议都是我不熟悉的编码术语建议,必须对其进行测试以查看编译器是否支持它们,并将尝试分别对它们进行响应.

Note: We do not have support for C++11. Thank you for the suggestions. Many are suggestions coding terms I'm unfamiliar with and will have to test to see if supported by compiler and will try and respond to each individually.

推荐答案

您可以将每个 progDefs.h 文件的内容包装到一个结构中,最好是直接包装,如果不能修改的话,就像这样:

You could wrap the contents of each progDefs.h file into a struct, preferably directly, or if you can't modify it, like this:

struct Version1 {
#include "version1\progDefs.h"
};

然后,您可以将 baseWriter 设置为模板类:

Then you can make baseWriter a template class:

template <typename Version>
class baseWriter
{
    using packet = typename Version::packet;
    using items = typename Version::items;

    void sendBookPacket() {
        packet pkt;
        pkt.type = items::BOOK_TYPE;
        sendNetworkPacket((void*)&pkt, sizeof(pkt));
    }
};

然后

using version1Writer = baseWriter<Version1>;
using version2Writer = baseWriter<Version2>;

更新:
如果C ++ 11不可用,则将上面代码中的 using X = Y 替换为 typedef Y X .也就是说,例如

Update:
If C++11 is not available, replace using X = Y in the code above to typedef Y X. That is, e.g

typedef typename Version::packet packet;

如果没有这些typedef,您也可以做所有事情,它们只是简化了代码.

You can also do everything without these typedefs, they just simplify the code a bit.

这篇关于针对同一接口的多个版本的C ++设计(头文件中的枚举/结构)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆