以下面简化的 C++ 类层次结构为例。我想要完成的是 Service
提供一个虚拟方法来保存任意 Model
对象。但是 Service
的每个子类,例如BoxService
应该而且只能保存 Box
对象。
由于 C++ 不支持方法参数中的协变,我无法简单地在 BoxService.h
中声明 save 方法,如下所示:
void save(Box box);
我的问题是,对于这个问题是否有任何首选的设计模式或最佳实践?或者如果到达的 Model 对象是 Box 类型,我应该检查 BoxService.cpp 中保存函数的实现,否则抛出异常?
模型.h
class Model {
private:
int id;
};
Box.h
class Box : public Model {
private:
int size;
};
Service.h
class Service {
public:
virtual void save(Model model);
};
BoxService.h
class BoxService : public Service {
public:
void save(Model box);
};
BoxService.cpp
void BoxService::save(Model box) {
// TODO: save box and make sure that box is of type 'Box' and not any other subtype of 'Model'
}
最佳答案
这可能是一种更实用的方法:
将每个模型类型与其实现配对:
template<typename T, typename ExtraType>
struct WithType {
T value;
using extra_type = ExtraType;
WithType(T value) : value(value) {}
};
将模型
定义为变体而不是继承层次结构:
using Model = std::variant<WithType<Box, BoxService>, WithType<X, XService>>;
现在访问变体:
class Service {
public:
void save(Model m) const {
visit([](auto withService) {
typename decltype(withService)::extra_type service;
service.save(withService.value);
}, m);
}
void remove(Model m) const {
visit([](auto withService) {
typename decltype(withService)::extra_type service;
service.remove(withService.value);
}, m);
}
};
关于C++ 协变参数 - 设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42867996/