在C++中填充地图容器时的多晶型设计
Polymorph design when filling a map container in C++
我不擅长OOP设计,但我需要向潜在雇主展示我的知识。情况如下:
我有一个包含键值类型参数的文件,称为 parameters.txt
。我有一个map <string, CommonParamValue>
作为容器。我需要用元素填充它,使用带有参数的文件。键始终是一个std::string
参数,CommonParamValue
可以用int
、double
、string
和标准函数调用来表示。为了实现这一点,CommonParamValue
是一个带有虚拟方法的基类。它有孩子 - StringParamValue
,DoubleParamValue
,CurTimeParamValue
。基类和每个子类都有一个返回内部数据的字符串表示形式的方法virtual string GetValue()
; virtual void SetValue(string)
设置值。
问题是如何使用多态性在运行时用适当的数据填充容器map <string, CommonParamValue>
?现在我有这样的情况:
参数.txt
*user_name=Jane
*order_number=1325
current_date=
填充地图的例程
ifstream in(fileParamsPath);
if (! in)
{
cout << "Cannot open file with parameters, program is terminating." << endl;
cin.get();
exit(-1);
}
string key = "", value = "";
while(in)
{
getline(in, key, '=');
getline(in, value, 'n');
// put key and value into the container
// right here we need to analyze the data type and choose appropriate container.
// CommonParamValue *paramValue = new DoubleParamValue(); or
// CommonParamValue *paramValue = new CurTimeParamValue(); or
// CommonParamValue *paramValue = new StringParamValue();
paramValue->SetValue(value);
params.insert(make_pair(key, *paramValue)); // params is a map <string, CommonParamValue>
delete paramValue;
}
in.close();
有一个想法是将值参数的类型保留在文件parameters.txt
中,并在填充时对其进行分析map <string, CommonParamValue>
参数.txt
*user_name=Jane
string
*order_number=1325
int
current_date=
function
并通过以下方式修改填充map <string, CommonParamValue>
例程:
string key = "", value = "", type = "";
while(in)
{
getline(in, key, '=');
getline(in, value, 'n');
getline(in, type, 'n');
in.get(); // got the dividing empty string
// put key and value into the container
// right here we need to analyze the data type and choose appropriate container.
if(type == "int")
{
CommonParamValue *paramValue = new IntParamValue();
}
else if(type == "function")
{
CommonParamValue *paramValue = new CurTimeParamValue();
}
else if(type == "string")
{
CommonParamValue *paramValue = new StringParamValue();
}
else
{
// error
exit(1);
}
paramValue->SetValue(value);
params.insert(make_pair(key, *paramValue)); // params is a map <string, CommonParamValue>
delete paramValue;
}
这是一个好决定还是坏决定?也许我的潜在雇主希望我以其他方式实施它,但我只有这个决定。对于初级C++程序员来说,还有更好的方法吗?
最经典的设计是工厂方法设计。
CommonParamValue* createParamValue( const std::string &value );
createParamValue
方法负责创建适当的派生ParamValue
并将其作为CommonParamValue
返回。
通过使用值字符串推断类型,可以避免将"type"的其他字符串泵入parameters.txt
createParamValue
内部。正则表达式听起来像是int
、double
和CurTime
最优雅的。Boost 正则表达式是一个示例库,可让您在 c++ 中执行此操作。但是,当然,如果您正在寻找快速解决方案,那么编写自己的30行决策树对于这些简单的语法来说应该不是问题。
客户端代码中的 if 语句对我来说看起来有点不稳定。可以尝试工厂课程吗?
具有基类 IParamValue
IntParamValue : public IParamValue { }
static IParamValue * Create(string selection);
IParamValue * IParamValue::Create(string selection)
{
if (selection == "int") return new IntParamValue();
...
}
客户端代码:
IParamValue* param = IParamValue::Create ("something");
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 错误处理.将系统错误代码映射到泛型
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 链表的泛型函数remove()与成员函数remove)
- 如何为 C 型字符串数组编写 getter 和 setter?
- C 字符串返回字符串的整数/双精度/长整型值
- 是什么导致了这种使用三进制而不是短整型的有符号int到无符号int转换
- 无法在 Arduino 中uint8_t数组转换为无符号长整型数组
- 给定一个类型,如何派生一个泛型更广泛的类型(例如,用于溢出安全求和)?
- 模板化接口 - 创建一个泛型模板类以返回任何容器
- 如何编写将要继承的泛型代码?
- C++17 如何保存泛型可调用对象以供以后使用
- 使用宏扩展的泛型:为什么指令缓存使用不当?
- 从.txt文件中读取浮点型数字并在公式中使用它们
- C++泛型类错误,问题出在哪里?
- C++泛型类,单独实现?
- 序列化多晶型接口
- 在C++中使用克隆方法实现多晶型效果
- 在C++中填充地图容器时的多晶型设计
- 使用多晶型载体与多晶型阵列之间的差异