我有以下代码,希望简化并尽量减少重复。
// Gather.cpp
void GetParam()
{
ProParameter * param; // 3rd party struct
ProParamvalue proValue; // 3rd party struct
ProParameterValueGet( param, & proValue ); // this is a call to a 3rd Party API
shared_ptr< CPartParam > pParam; // CPartParam is my class
/* The .type in switch() statement is an enum with following definition:
typedef enum param_value_types {
PRO_PARAM_DOUBLE = 50, /* use d_val from ProParamvalueValue to set value *
PRO_PARAM_STRING = 51, /* use s_val from ProParamvalueValue to set value *
} ProParamvalueType;
*/
// WUD LOVE TO ELIMINATE THE SWITCH-CASE
switch( proValue.type ) // .type is enum as above
{
case PRO_PARAM_DOUBLE: // 3rd party enum value
pParam->SetValue( proValue.value.d_val );
break;
case PRO_PARAM_STRING: // 3rd party enum value
pParam->SetValue( proValue.value.s_val );
break;
default:
break;
}
}
// PartData.h
class CPartParam
{
public:
enum ValueType
{
DOUBLE,
STRING
};
ValueType m_eValueType;
double m_dVal;
wstring m_sVal;
bool SetValue( const double & dVal );
bool SetValue( const wstring & sVal );
};
// PartData.cpp
// There is one overload for each data-type. WUD LOVE TO CONDENSE TO A SINGLE METHOD/TEMPLATE FUNCTION THAT CAN SET THE VALUE IRRESPECTIVE OF THE DATA-TYPE.
void CPartParam::SetValue( const double & dVal )
{
m_eValueType = DOUBLE;
m_dVal = dVal;
}
bool CPartParam::SetValue( const wstring & sVal )
{
m_eValueType = STRING;
m_sVal = sVal;
}
可以看出,“proValue.type”的数据类型是在运行时确定的,这迫使我编写重复的代码:CPartParam :: SetValue()重载(每个数据类型一个)。如果可以避免GetParam()中的switch-case循环,我会喜欢它,如果可能的话。
当必须检索存储在CPartParam shared_ptr中的数据时,有更多重复代码和第二个switch-case(即CPartParam :: GetValue)。
我已经展示了示例代码(可能不一定编译),但如果有人想编译,将会修复。
我只展示了两种数据类型(PRO_PARAM_DOUBLE,PRO_PARAM_STRING),但还有一些数据类型。
我唯一的限制是我们的开发团队仍然使用Boost 1.36.0,Visual Studio 2005(主要原因是第三方库)。我们需要使用boost :: serialization,因此使用任何新数据类型的建议都有限制,新的数据类型必须使用boost版本1.36.0中的boost :: serialization进行序列化。
答案 0 :(得分:4)
看看Boost.Variant(可在Boost 1.36.0中使用)。这提供了一个variant
类型,它封装了受歧视的联合(取代了CPartParam
类型),以及一个代替切换的static_visitor
惯用语。
答案 1 :(得分:2)
您正在寻找运行时继承。最好的解决方案实际上是boost::variant
,它经过了很好的优化等等。