gpt4 book ai didi

c++ - 更通用的访问者模式

转载 作者:可可西里 更新时间:2023-11-01 16:40:08 24 4
gpt4 key购买 nike

如果我的问题太长且技术性很强,我很抱歉,但我认为让其他人对此感兴趣非常重要

我一直在寻找一种方法来将一些软件内部结构与其在 C++ 中的表示清楚地分开

我有一个通用参数类(稍后将存储在一个容器中),它可以包含任何类型的 boost::any 类值

我有一个(大致)这样的基类(当然还有更多的东西)

class Parameter 
{
public:
Parameter()
template typename<T> T GetValue() const { return any_cast<T>( _value ); }
template typename<T> void SetValue(const T& value) { _value = value; }
string GetValueAsString() const = 0;
void SetValueFromString(const string& str) const = 0;
private:
boost::any _value;
}

派生类有两层:第一级定义类型和到/从字符串的转换(例如 ParameterInt 或 ParameterString)第二层定义行为和真正的创建者(例如从 ParameterInt 派生 ParameterAnyInt 和 ParameterLimitedInt 或从 GenericString 派生 ParameterFilename)

根据实际类型,我想添加外部函数或根据特定参数类型操作的类,而不向基类添加虚拟方法,也不需要进行奇怪的强制转换

例如,我想根据参数类型创建适当的 gui 控件:

Widget* CreateWidget(const Parameter& p)

当然,除非我使用 RTTI 或自己实现它(使用枚举和开关盒),否则我无法从中理解真正的参数类型,但这不是正确的 OOP 设计解决方案,你知道的。

经典的解决方案是访客设计模式 http://en.wikipedia.org/wiki/Visitor_pattern

这种模式的问题是我必须事先知道将实现哪些派生类型,所以(将维基百科中的内容和我的代码放在一起)我们将有:

struct Visitor 
{
virtual void visit(ParameterLimitedInt& wheel) = 0;
virtual void visit(ParameterAnyInt& engine) = 0;
virtual void visit(ParameterFilename& body) = 0;
};

是否有任何解决方案可以以任何其他方式获得此行为,而无需提前知道所有具体类型并且无需派生原始访问者?


编辑: Dr. Pizza's solution seems the closest to what I was thinking , 但问题仍然相同,该方法实际上依赖于 dynamic_cast,我试图将其作为一种(即使很弱)RTTI 方法来避免

也许最好在不引用访问者模式的情况下思考一些解决方案并清理我们的思想。目的只是具有这样的功能:

Widget* CreateWidget(const Parameter& p)

在不丢失其类型信息的情况下,对每个“具体”参数表现不同

最佳答案

对于 Vistor 的通用实现, 我建议 Loki Visitor , 的一部分 Loki library .

关于c++ - 更通用的访问者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31913/

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