再次思考起模板同虚函数(继承)在实现接口(interface)上的异同,写了两个例子来比较了一下
经典的虚函数实现接口方式
A定义了接口f(),A的子类必须实现这个接口
看模板的实现方法
经典的虚函数实现接口方式
/**/
/* vfunctions usage cases */
class A
... {
public:
virtual void f() = 0;
} ;
class B
: public A
... {
public:
void f() ...{ cout<<"b"; };
} ;
class C
: public A
... {
public:
void f() ...{ cout<<"c"; };
} ;
void test_vfunc()
... {
A *pa = new C;
pa->f();
delete pa;
}
class A
... {
public:
virtual void f() = 0;
} ;
class B
: public A
... {
public:
void f() ...{ cout<<"b"; };
} ;
class C
: public A
... {
public:
void f() ...{ cout<<"c"; };
} ;
void test_vfunc()
... {
A *pa = new C;
pa->f();
delete pa;
}
看模板的实现方法
/**/
/* template usage cases */
template < typename T >
class TB
... {
private:
T t;
public:
void f() ...{ cout<<"tb"; };
} ;
template < typename T >
class TC
... {
private:
T t;
public:
void f() ...{ cout<<"tc"; };
} ;
/**/ /* a class template without a f() member function */
template < typename T >
class TE
... {
private:
T t;
public:
void ff() ...{ cout<<"tf"; };
} ;
template < typename T, typename TFUNC_T >
class TD
... {
private:
T t;
public:
void myfunc()
...{
TFUNC_T a;
a.f();//require TFUNC_T must has a member function named f()
};
} ;
void test_template()
... {
//TD<int,TC<int> > d;
TD<int, TE<int> > d;
d.myfunc();
}
template < typename T >
class TB
... {
private:
T t;
public:
void f() ...{ cout<<"tb"; };
} ;
template < typename T >
class TC
... {
private:
T t;
public:
void f() ...{ cout<<"tc"; };
} ;
/**/ /* a class template without a f() member function */
template < typename T >
class TE
... {
private:
T t;
public:
void ff() ...{ cout<<"tf"; };
} ;
template < typename T, typename TFUNC_T >
class TD
... {
private:
T t;
public:
void myfunc()
...{
TFUNC_T a;
a.f();//require TFUNC_T must has a member function named f()
};
} ;
void test_template()
... {
//TD<int,TC<int> > d;
TD<int, TE<int> > d;
d.myfunc();
}
这个例子有些复杂,不过比较接近实际中的用法,模板类TD的myfunc()实现里面需要用到模板参数TFUNC_T,而且暗喻了TFUNC_T需要有一个f()的成员函数,如果TFUNC_T模板参数没有f()的成员函数而myfunc()又被实例化了,a.f()将会报错。
两种方法在某种程度上都实现了接口,虚函数是预先定义了一套接口,要求其子类去实现它们,不管实际中有没有用到;而模板则是要求作为模板参数的类型必须满足某些接口(特性)。
现在我还不能够给出何时使用虚函数,何时使用模板的一个指导,或许在以后补充。