我正在将文件转换代码从专有文件格式编写为更通用的文件格式。我的目标是支持制造商文件格式的多个版本。
我有相同专有标头的多个版本。标题定义了构成主文件头的各种结构(文件只是一个大标题,后跟原始数据)。
我需要读取源文件的前4个字节来确定文件版本。反过来,文件版本告诉我使用哪个版本的C-structs来创建文件。
问题是:
可能的解决方案:
我尝试过使用命名空间进行黑客攻击:
namespace version1 {
#include "version1.h"
}
namespace version2 {
#include "version2.h"
}
int main (void) {
version1::header *hdr = new version1::header;
return 0;
}
但是这不会起作用因为包含警戒,并且因为每个标题中都重新定义了多个宏。
有没有一种优雅的方法来处理这个问题?
答案 0 :(得分:5)
您可以使用两个不同的源文件以及前向声明:
// Forward declare in main.cpp:
namespace version1
{
struct header;
}
namespace version2
{
struct header;
}
// version1.cpp:
namespace version1
{
#include <version1.h>
}
version1::header* new_v1_header()
{
return new version1::header;
}
// other functions using `version1::header`
// version2.cpp:
namespace version2
{
#include <version2.h>
}
version2::header* new_v2_header()
{
return new version2::header;
}
// other functions using `version2::header`
另一种方法是实现一个包装类,它有一个只是空shell的基类:
class header_base
{
virtual int func1(char *stuff) = 0;
... many other virtual functions.
};
// Create implementation of header_v1 or header_v2:
header_base* make_header(unsigned int magic);
header_base.cpp:
#include "header_v1.h"
#include "header_v2.h"
header_base* make_header(unsigned int magic)
{
switch(magic)
{
case Magic_V1:
return new header_v1;
case Magic_V2:
return new header_v2;
default:
assert(0);
return 0;
}
}
然后在两个单独的
中实现 在headerv1.h中:
class header_v1 : public header_base
{
int func1(char *stuff);
...
};
header_v1.cpp:
#include "header1.h"
int header_v1::func1(char *stuff)
{
...
return 17;
}
类似于header_v2.h和header_v2.cpp。