【发布时间】:2020-12-17 04:28:56
【问题描述】:
我已经处理了几天的问题,但仍然没有适当的解决方案。想象一下,我有几种(数量可能不同)乐器。每个仪器产生不同类型的数据。对于每种乐器,我都有一个结构(我在这里展示了非常简单的近似值):
struct TInstrument1 {
int Variable1;
int Variable2;
}
struct TInstrument2 {
int Variable3;
}
我正在尝试创建一种数据库来查看可用数据。我这样做的方法如下:
首先,我有一个做文件映射的类。我在 Windows 上编程,所以我在 MapFile 函数中使用 CreateFile、CreateFileMapping、MapViewOdFile 函数:
template <class SType> class TFileMapping {
HANDLE hFile;
HANDLE hFileMap;
SType * MapView;
TFileMapping();
~TFileMapping();
void MapFile(String FileName,DWORD FileAccessType,DWORD FileSharing,DWORD MappingAccessType,DWORD MapViewAccessType,DWORD FlagsAndAttributes,DWORD CreationDisposition,size_t ByteNum);
void UnMapFile();
};
然后在TMapVector结构中使用这个类(我给出一个简化版本):
template <class SType> struct TMMapVector : public TFileMapping<SType> {
String MappedFileName;
unsigned int * AssignedLen;
unsigned int * Num;
SType * Data;
TMMapVector();
~TMMapVector();
void MapVector(String FileName);
void AppendItem(SType * Val);
int size();
};
这个想法是,例如TMapVector<Instrument1> 创建/打开一个与Instrument1 对应的数据库文件,并包含一个Instrument1 类型的对象。
现在我的问题是我不知道用户拥有多少种仪器。目前有 3 个,但代码应该很容易扩展到更多的仪器类型。目前我处理如下。我有一个课程TFileInfo 有两种乐器类型,但只有一个被填满。这让我可以进一步使用std::vector<TFileInfo>。这种方法的问题在于,每次我需要使用仪器做某事时,我都必须使用 switch 语句:
struct TFileInfo {
TMMapVector<TInstrument1> Instrument1;
TMMapVector<TInstrument2> Instrument2;
};
struct TDataBase {
std::vector<TFileInfo> FileInfo;
std::vector<char> InstrumentType;
int GetNumberOfItemsInArchive(int ArchIdx);
}
int TDataBase::GetNumberOfItemsInArchive(int ArchIdx) {
switch InstrumentType[ArchIdx] {
case 1:
return(FileInfo[ArchIdx].Instrument1.size());
case 2:
return(FileInfo[ArchIdx].Instrument2.size());
}
}
想象一下,如果我需要再添加 10-100 种乐器,当然我不仅有 size() 函数,还有更多。有没有更简单的方法来实现这个?我在考虑接口,但是(1)如果我理解正确的虚函数不能与模板一起使用,(2)我对数据执行相同的操作,只是类型不同。非常感谢您的建议。
【问题讨论】:
-
Now the problem I have is that I do not know how my types of instruments a user has这是否意味着您不知道仪器的数量或您不知道仪器类型的数量?我怀疑你在那句话的某处有一个类型:) -
@Exagon 抱歉不够精确。我不知道有多少仪器,用户应该能够添加/删除仪器。关于类型,目前我已经实现了一定数量的工具。但是将来客户可能会要求添加更多的仪器类型,因此代码必须易于扩展。这就是我说的类型的数量不知道的意思。
-
__fastcall看起来很可疑。它不能在那里,因为&TFileMapping::MapFile被用作 Windows 函数的回调。 Windows 根本不理解指向成员函数的指针,所以__fastcall毫无意义。 -
@Alexander Sure you can,但你不能让它成为
Base接口的一部分。virtual函数不能是函数模板,但virtual函数可以是class模板的一部分。 -
@Alexander 不,您需要添加序列化支持以某种方式保存/恢复您的实例树。也许您可以为它使用现有的库,或者为它编写自己的支持类。
type#hash_or_address#instance_data可能会被写入文件,当恢复时,您需要将hash_or_address映射到新实例重新连接指针树的任何地方。我还没想好。可能有陷阱:-)
标签: c++ templates vector file-mapping