gpt4 book ai didi

c++ - 如何让一个接口(interface)返回不同的数据类型?

转载 作者:太空狗 更新时间:2023-10-29 23:16:57 24 4
gpt4 key购买 nike

简而言之,我想使用一个接口(interface) IProducer 来创建一个对象 IProductIProduct 将具有不同的组件,具体取决于创建它的接口(interface)。 IProduct 类随后将由 IConsumer 接口(interface)使用。应根据 IProduct 的派生类型使用正确的 IConsumer 类(我不想自己进行类型检查)。

我基本上想使用策略模式(单个接口(interface)背后的不同行为),但增加了返回特定于所使用的派生接口(interface)的对象的能力。我想遵守打开/关闭原则,并且在添加更多功能时不更改任何这些现有类。

我想完成这样的事情(我确定某处语法错误但请耐心等待):

class IProduct {
public:
int intData;
};

class ProductA : public IProduct {
public:
float floatData;
};

class ProductB : public IProduct {
public:
bool boolData;
};

class IProducer {
public:
virtual IProduct* produce(void) = 0;
};

class ProducerA : public IProducer {
public:
IProduct* produce(void) {
return new ProductA;
}
};

class ProducerB : public IProducer {
public:
IProduct* produce(void) {
return new ProductB;
}
};

class IConsumer {
public:
virtual void consume(IProduct* prod) = 0;
};

class ConsumerA : public IConsumer {
public:
void consume(IProduct* prod) {
//I want to access the float!
}
};

class ConsumerB : public IConsumer {
public:
void consume(IProduct* prod) {
//I want to access the bool!
}
};

void main() {

IProducer* producer = ProducerFactory::create("ProducerA");

IProduct* product = producer->produce();

IConsumer* consumer = ConsumerFactory::create("ConsumerA");

consumer->consume(product); //I would like the correct consumer to be used here to deal with the ProductA class
}

如果您认为有更好的方法来解决这个问题,我会洗耳恭听。感谢您的帮助!

最佳答案

您需要的是一个注册表,它将 IProduct 实现映射到正确的 IConsumer 实现。基本上它只是 map 的抽象:

class ConsumerRegistry
{
std::map<size_t, std::shared_ptr<IConsumer>> m_consumers;

public:

// we are not responsible for products, so lets allow plain ptrs here for more flexibility and less overhead
std::shared_ptr<IConsumer> GetConsumer(IProduct* product)
{
auto it = m_consumers.find(typeid(product).hash_code());

if (it == m_consumers.end())
return nullptr;
else
return it->second;
}

template<typename P>
void RegisterConsumer(std::shared_ptr<IConsumer> consumer)
{
m_consumers.emplace(typeid(P).hash_code(), consumer);
}

template<typename P>
void UnregisterConsumer()
{
m_consumers.erase(typeid(P).hash_code());
}
};

要么全局公开此类(例如作为单例),要么在需要它的上下文中使用它。您这样注册消费者:

reg.RegisterConsumer<ProductA>(new ConsumerA());
reg.RegisterConsumer<ProductB>(new ConsumerB());

我们还可以在 IConsumer 中使用一个 virtual void Register(ConsumerRegistry& reg) = 0; 方法来实现更安全的注册:

void ConsumerA::Register(ConsumerRegistry& reg, std::shared_ptr<IConsumer> self)
{
IConsumer::Register<ProductA>(reg, self);
}

// Required for friendship, can be static:
template<typename T>
void IConsumer::Register(ConsumerRegistry& reg, std::shared_ptr<IConsumer> self)
{
reg->RegisterConsumer<T>(self);
}

void ConsumberRegistry::RegisterConsumer(std::shared_ptr<IConsumer> consumer)
{
consumer->Register(*this, consumer);
}

Register() 和低级 RegisterConsumer() 方法设为私有(private),并让 ConsumerRegistryIConsumer 成为 friend 。可以这样使用:

reg.RegisterConsumer(new ConsumerA());
reg.RegisterConsumer(new ConsumerB());

关于c++ - 如何让一个接口(interface)返回不同的数据类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21317403/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com