The problem is: There are some math expressions, which have +/-/*// operators. But they can be implemented in different math libraries. And different math libraries implementation cannot be calculated directly. How to design the expression classes?
Design by having a base class:
class Expr;
class LPExpr: public Expr
{
operate();
};
class XXExpr: public Expr
{
operate();
};
Expr operator+(const Expr&, const Expr&);
The difficulty is, in operator+, since they may be in different implementation, it may need to open up some common interface in Expr. But somtimes, the value needs a specific class type interface to retrieve.
By Template:
The below implementation is done by template. it can solve the problem of different types of expressions calculations because the implementation is done in template specialization, no need to be defined in definitions. The design defines almost the thinnest interface for expressions. What we want are, the class name and the operators only. Especially, it is suitable for the operations implementations between base classes.
class LPType;
class XXType;
template<class T>
class Expr;
template<class T>
class Factory
{
public:
Expr<T> * create();
};
template<class T>
Expr<T> operator+(const Expr<T>&, const Expr<T> &);
template<>
class Expr<LPType>
{
public:
Expr()
{
cout << "Expr() LPType" << endl;;
}
private:
int m_env;
};
template<>
class Factory<LPType>
{
public:
Expr<LPType>* create()
{
cout << "creating expr LPType" << endl;
return new Expr<LPType>();
}
};
template<>
Expr<LPType> operator+(const Expr<LPType>&, const Expr<LPType> &)
{
Expr<LPType> lpType;
cout << "operator+ LPType";
lpType.m_env;
return lpType;
}
template<>
class Expr<XXType>
{
public:
Expr()
{
cout << "Expr() XXType" << endl;;
}
};
template<>
class Factory<XXType>
{
public:
Expr<XXType>* create()
{
cout << "creating expr XXType" << endl;
return new Expr<XXType>();
}
};
template<>
Expr<XXType> operator+(const Expr<XXType>&, const Expr<XXType> &)
{
Expr<XXType> lpType;
cout << "operator+ XXType";
return lpType;
}
int main()
{
Factory<LPType> lpFactory;
Expr<LPType>* lpType1 = lpFactory.create();
Expr<LPType>* lpType2 = lpFactory.create();
*lpType1 + *lpType2;
Factory<XXType> xxFactory;
Expr<XXType>* xxType1 = xxFactory.create();
*lpType1 + *xxType1; // cannot compiled
return 0;
}
No comments:
Post a Comment