你会使用void指针吗?
No.
通用类(PacketBasicInterface)如何提供通用(部分)接口来查询有关数据包类型(以便可以在运行时作出任何决定)?
这对我最有意义。
让我细化一下。是的,拥有一个通用基类将是一件好事。但是,解析流以构造基类的子类型时,不要依赖于类型方法。而是使用工厂模式。让各个工厂根据键构建正确的对象类型,我假设这些键可以从正在分析的数据中获得。
如果您在数据中遇到字符串"PacketTypeA"
,则预计PacketTypeAFactory
将负责构建该对象。
FWIW,这种方法可以扩展许多基类的子类型。我们在工作中使用这种方法,并且在二十多年的时间里为我们提供了很好的服务。
下面的代码基础,我想的骨骼结构:
的类。
class PacketBasicInterface { };
class PacketTypeA : public PacketBasicInterface { };
class PacketTypeB : public PacketBasicInterface { };
工厂的接口。
// PacketFactory.h
class PacketFactory
{
public:
static PacketBasicInterface* makePacket(std::string const& packetData);
static void registerFactory(std::string const& key, PacketFactory* factory);
virtual PacketBasicInterface* make(std::string const& packetData) = 0;
virtual ~PacketFactory() {}
};
实施,使工厂的工作框架。
// PacketFactory.cpp
#include "PacketFactory.h"
namespace PacketBasicInterface_Impl
{
using PacketFactoryMap = std::map<std::string, PacketFactory*>;
PacketFactoryMap& getPacketFactoryMap()
{
static PacketFactoryMap theMap;
return theMap;
}
};
uisng namespace PacketBasicInterface_Impl;
PacketBasicInterface* PacketFactory::makePacket(std::string const& packetData)
{
std::string key = extractKey(packetData);
PacketFactoryMap& theMap = getPacketFactoryMap();
PacketFactoryMap::iterator iter = theMap.find(key);
if (iter == theMap.end())
{
return nullptr;
}
return iter->second->make(packetData);
}
void registerFactory(std::string const& key, PacketFactory* factory)
{
getPacketFactoryMap()[key] = factory;
}
代码使用工厂模式使型PacketTypeA的对象。
// PacketTypeAFactory.cpp
#include "PacketFactory.h"
#include "PacketTypeA.h"
class PacketTypeAFactory : public PacketFactory
{
public:
virtual PacketBasicInterface* make(std::string const& packetData)
{
PacketTypeA* packet = new PacketTypeA();
// Flesh out packet with data pulled from packetData
// ...
//
return packet;
}
struct Initializer
{
Initializer() { PacketFactory::registerFactory("PacketTypeA", new PacketTypeAFactory); }
};
};
// Constructing this object at static initialization time makes sure
// that PacketTypeAFactory is registered with PacketFactory when the
// stream data need to be parsed.
static PacketTypeAFactory::Initializer initializer;
制备型PacketTypeB的对象的代码非常类似于 代码使用工厂模式使型PacketTypeA的对象。
// PacketTypeBFactory.cpp
#include "PacketFactory.h"
#include "PacketTypeB.h"
class PacketTypeBFactory : public PacketFactory
{
public:
virtual PacketBasicInterface* make(std::string const& packetData)
{
PacketTypeA* packet = new PacketTypeA();
// Flesh out packet with data pulled from packetData
// ...
//
return packet;
}
struct Initializer
{
Initializer() { PacketFactory::registerFactory("PacketTypeB", new PacketTypeBFactory); }
};
};
// Constructing this object at static initialization time makes sure
// that PacketTypeBFactory is registered with PacketFactory when the
// stream data need to be parsed.
static PacketTypeBFactory::Initializer initializer;
客户端代码。
std::string packetData;
while (getPacketData(packetData))
{
PacketBasicInterface* packet = PacketFactory::makePacket(packetData);
if (packet == nullptr)
{
// Deal with error.
}
else
{
// Use packet
}
}
不知道到底你需要什么,但某种抽象工厂,或复合的? –