模板类内部能否含有虚函数?

首先,我们要区分模板类虚函数和模板虚函数,话不多说,先上代码:

模板类虚函数
template<class T>
class A{
public:
	virtual ~A(){}
	virtual void foo(T &t){}
};

template<class T, class R>
class B : public A<T>{
	R *r;
public:
	void foo(T &t) override{}
};

//模板虚函数
class A{
public:
	virtual ~A(){}
	template<class T>
	virtual void foo(T &t){}
};

class B : public A{
public:
	template<class T>
	void foo(T &t) override{}
};

显然模板虚函数无法通过编译,至于为什么?深究一下C++多态的实现原理,就能知道为什么不允许定义模板虚函数。

C++的多态是通过虚表实现的,对于含有虚函数的类,会为其定义一个虚表,每个实例化的对象都有一个指向该虚表的指针,所以同样的类,含有虚函数的类的实例大小比不含虚函数的多上一个指针的大小,虚表里为每个虚函数维护着一条跳转记录,这些跳转地址在编译期就被确定了,存放在类定义模块的数据段中,在程序运行期是不可修改的。

那么这跟模板虚函数有什么关系呢?
C++对于模版的处理,在编译时,编译器只对已经实例化的模板类生成对应的模板类代码,假如这些类中定义的有模板类虚函数,则对每个实例化的模板类型创建一个虚表,即第一种情况 —— 模板类虚函数,是可行的。

再看看模板虚函数为什么不行?
如上面的代码,A是一个类型,它含有模板虚函数,虽然是虚函数,但是函数符号并不确定,因为不知道模板T是一个什么类型,对于从没调用过这个模板函数的情况下,这个模板虚函数甚至都不会实例化,那么就相当于没有虚函数了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值