重构以下两个C++方法以移出重复的代码

oss*_*cad 8 c++ refactoring

我有以下两种方法(如你所见)在大多数语句中都是类似的,除了一种(详见下文)

unsigned int CSWX::getLineParameters(const SURFACE & surface, vector<double> & params)
{
    VARIANT varParams;

    surface->getPlaneParams(varParams); // this is the line of code that is different

    SafeDoubleArray sdParams(varParams);

    for( int i = 0 ;  i < sdParams.getSize() ; ++i )
    {
        params.push_back(sdParams[i]);
    }

    if( params.size() > 0 ) return 0;
    return 1;
}

unsigned int CSWX::getPlaneParameters(const CURVE & curve, vector<double> & params)
{
    VARIANT varParams;

    curve->get_LineParams(varParams); // this is the line of code that is different

    SafeDoubleArray sdParams(varParams);

    for( int i = 0 ;  i < sdParams.getSize() ; ++i )
    {
        params.push_back(sdParams[i]);
    }

    if( params.size() > 0 ) return 0;
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

是否有任何技术可以用来将两种方法的公共代码行移到一个单独的方法中,可以从两个变量中调用 - 或者 - 可能将两种方法组合到一个方法中?

以下是限制:

  1. SURFACE和CURVE类来自第三方库,因此无法修改.(如果它有助于它们都来自IDispatch)
  2. 还有更多类似的类(例如FACE)可以适应这个"模板"(不是C++模板,只是代码行的流程)

我知道以下可能(可能?)实现为解决方案,但我真的希望有更好的解决方案:

  1. 我可以为2个方法添加第3个参数 - 例如枚举 - 标识第一个参数(例如enum :: input_type_surface,enum :: input_type_curve)
  2. 我可以传递一个IDispatch和尝试的dynamic_cast <>和测试,转换是NON_NULL,做一个if-else语句来调用正确的方法(如getPlaneParams()与get_LineParams())

以下不是限制,但由于我的队友阻力,这将是一个要求:

  1. 没有实现从SURFACE/CURVE等继承的新类(他们更愿意使用我上面提到的枚举解决方案来解决它)

GMa*_*ckG 11

想到几个想法,但这是我认为最好的:

namespace detail
{
    void getParameters(const SURFACE& surface, VARIANT& varParams)
    {
        surface->getPlaneParams(varParams);
    }

    void getParameters(const CURVE& curve, VARIANT& varParams)
    {
        curve->get_LineParams(varParams);
    }
}

template <typename T>
unsigned int getParameters(const T& curve, vector<double> & params)
{
    VARIANT varParams;
    detail::getParameters(curve, varParams);

    SafeDoubleArray sdParams(varParams);
    for( int i = 0 ;  i < sdParams.getSize() ; ++i )
    {
        params.push_back(sdParams[i]);
    }

    return params.size() != 0;
}
Run Code Online (Sandbox Code Playgroud)

您所做的是将获取参数的任务委托给其他一些过载的函数.只需为您拥有的每种不同类型添加类似的功能.(注意,我简化了你的退货声明.)


Car*_*ter 5

提取方法.在标记为不同的行之后的所有内容都是相同的 - 因此将其提取为从两种原始方法调用的方法.