你會使用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
}
}
不知道到底你需要什麼,但某種抽象工廠,或複合的? –