简体   繁体   中英

Refactoring a class

I have two almost identical classes, in fact every member function is identical, every member is identical, every member function does exactly the same thing. The only difference between those classes is the way I can define variable of their type:

AllocFactorScientific<102,-2> scientific;
AllocFactorLinear<1.2> linear;  

Here are headers for them:

template<double&& Factor>
struct AllocFactorLinear;

template<short Mantissa, short Exponent, short Base = 10>
struct AllocFactorScientific

My question is how can I refactor those functions out of those classes that would allow me to have just one set of functions and not two sets of identical functions.

Extract all the common behavior in a third class (I'm omitting the template arguments in my answer for the sake of clarity) :

class CommonImpl
{
public:
  void doSomething() {/* ... */ }
};

I then see two choices (which are, from my point of view at least, pretty much equivalent) :

  • Make AllocFactorLinear and AllocFactorScientific inherit privately from this class, and bring the member functions you wish to expose in scope with a using directives :

     class AllocFactorLinear : CommonImpl { public: using CommonImpl::doSomething; }; 
  • Aggregate the implementation class in AllocFactorLinear and AllocFactorScientific and forward all the calls to the private implementation :

     class AllocFactorLinear { public: void doSomething() { impl_.doSomething(); } private: CommonImpl impl_; }; 

I would personally go for the first solution.

也许尝试使用此函数创建一些基类,并使用有关此基类继承的模板来完成这两个类。

Why do you use a templated class for this? Couldnt you use a untemplated class with 2 different constructors?

I think it would be something like:

template <typename Type>
struct AllocFactor {...};

and then you can have Type , for example:

template <double&& Factor>
struct LinearConfig
{
    static double value() { return Factor;}
};

and:

template <short Mantissa, short Exponent, short Base = 10>
struct FactorScientificConfig
{
    static double value() 
    {
       return some_expression_to_get_factor;
    }
};

You can create the AllocFactor using AllocFactor<LinearConfig<1.2>> and the corresponding with the FactorScientificConfig . Then you can use the static member function to return the value calculated for both the classes, so that AllocFactor<T> can use T::value() as the value reported by the config class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM