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 questi开发者_C百科on 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
andAllocFactorScientific
inherit privately from this class, and bring the member functions you wish to expose in scope with ausing
directives :class AllocFactorLinear : CommonImpl { public: using CommonImpl::doSomething; };
Aggregate the implementation class in
AllocFactorLinear
andAllocFactorScientific
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.
Maybe try with creating some base class with this functions and do this 2 classes with templates on inheritance of this base class.
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.
精彩评论