最近学习国外一个开发时间长达10年以上的开源C++代码,发现大量的traits萃取技术。查看网络对这个技术解释得非常难懂,现在用一个通俗易懂的列子来讲解下究竟是什么意思。
我的理解是C++算是底层语言,无法像java和C#一样运行期动态判断对象类型(如 is 等关键字)等信息。通过C++的模板萃取技术可以达到要求,且是通过编译后模板实列化后决定其行为,这样速度效率更高,代码更加简洁!
我先来提一个假设的需求,项目需要一个通用DrawerAll函数,能绘制我们系统中所有的图形,如:circle,Plygon,Rectangle等,同时画过程中可能要构建这种图形临时对象(就是要动态获取具体的图形类型)。绘制某种具体图形的算法上肯定有差异,但对使用DrawerAll的使用者来说并不关心这些,也应该不去关心这些,只需要调用DrawerAll函数,传入自己的图形就可以了。下面看看我们用Traits技术来实现。
class Polygon
{
};
class Rectangle
{
};
class Circle
{
};
template<class Shape>
class Drawer;
template<>
struct Drawer<Polygon>
{
typedef Polygon shape_type;//为算法器提取类型用
void Draw(shape_type sh)
{
}
shape_type Clone(shape_type sh)
{
return Polygon(sh);
}
};
template<>
struct Drawer<Circle>
{
typedef Circle shape_type;//为算法器提取类型用
void Draw(shape_type sh)
{
}
shape_type Clone(shape_type sh)
{
return Circle(sh);
}
};
template<>
struct Drawer<Rectangle>
{
typedef Rectangle shape_type;//为算法器提取类型用
void Draw(shape_type sh)
{
}
shape_type Clone(shape_type sh)
{
return Rectangle(sh);
}
};
template<class Shape>
void DrawAll(Shape sh)
{
typedef typename Drawer<Shape>::shape_type sh_type;//算法器提取的对应类型
sh_type cpsh = Drawer<Shape>().Clone(sh);//复制对象
Drawer<Shape>().Draw(sh);//画出图形
}
int main()
{
Polygon p;
Rectangle r;
Circle c;
//下面不同图形调用接口一致
DrawAll(p);
DrawAll(c);
DrawAll(r);
}
从代码看出,我们结构中没有使用继承和多态,也没有因为不同的图形类型增加if else ,甚至Switch等判断。编译出来后,执行绘制图形,自动进入了自己的图形的绘制函数,且这个是编译的时候就决定好了,多爽啊!这就是C++ trais萃取技术,在项目要求高效的条件下绝对是非常好的选择。
这是本人一点理解,如果有错误大神多请教!谢谢。