使用模板模拟虚函数

原创 2004年05月07日 22:01:00

使用模板模拟虚函数

先看一个简单的虚函数的例子

#include <iostream>
using namespace std;
class B
{
public:
    void Fun() { vf(); }
    virtual void vf() { cout << "B::vf" << endl; }
};
class D : public B
{
public:
    void vf() { cout << "D::vf" << endl; }
};

int main()
{
 D d;
 d.Fun();
 B* pd = NULL;
 pd = &d;
 pd->Fun();
}

它的输出也很简单, 没有什么可以解释的。

D::vf

D::vf


我们的目标是使用模板来重新实现它,下面便是具体实现:

#include <iostream>
using namespace std;
template<typename T>
class Base
{
public:
 void Fun()
 {
  T* pT = static_cast<T*>(this);
  pT->vf();
 }

 void vf()
 {
  cout << "Base::vf" << endl;
 }
};


class Derived : public Base<Derived>
{
public:
 void vf()
 {
  cout << "Drived:vf" << endl;
 }
};
int main()
{
 Derived derived;
 derived.Fun();
}

它的输出:

D::vf

我们的模板类真的实现了虚函数呀!其中关键的两条语句是:
class Derived : public Base<Derived>
T* pT = static_cast<T*>(this);

利用模板的好处是很明显的:首先是编译后的程序变小了,省去了vptr 和 vtable。
第二时效率,模板类在编译期完成了静态绑定,比起虚函数的执行期动态绑定,节省了对於指针的指针的调用。

如果模板真的那么强大,我想早就没有人用虚函数了。下面我们有必要谈一谈它的缺
点:

我们重新来改写main()函数
int main()
{
 Derived derived;
 derived.Fun();
 Base *pBase = &derived;
 pBase->Fun();

}
似乎没有问题,我们重新编译执行.......................报错了没有?报错的原因在於Base Class 后的尖括号,你必须声明那个<typename T>。我们重新改写一下

int main()
{
 Derived derived;
 derived.Fun();
 Base<Derived> *pBase = &derived;
 pBase->Fun();

}

重新编译执行,如果再有问题。那就是你自己的了。

模板是支持缺省值的,因此我们可以适当的偷下懒。将我们的基类改写一下。

template<typename T=Derived>
class Base
{
public:
 void Fun()
 {
  T* pT = static_cast<T*>(this);
  pT->vf();
 }

 void vf()
 {
  cout << "Base::vf" << endl;
 }
};

但即便如此,尖括号也是必须的。

int main()
{
 Derived derived;
 derived.Fun();
 Base<> *pBase = &derived;
 pBase->Fun();

}

 

for more information and simulation of virtual function with template, please refer to http://www.codeproject.com/cpp/SimulationofVirtualFunc.asp

模板成员函数为什么不能是虚函数

《Thinking in C++》volume 2第五章有这么一句话: Member template functions cannot be declared virtual.Current com...
  • jcwKyl
  • jcwKyl
  • 2009年01月13日 20:59
  • 14336

c++中的虚函数、虚基类、类模板

一、虚函数 首先要明白C++为什么要引进虚函数这个机制, 虚函数就是在基类中被关键字virtual说明,并在派生类中重新定义的函数。虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过...
  • zyazky
  • zyazky
  • 2016年08月15日 14:17
  • 1647

C++模板类的虚函数成员

C++模板类只有在被使用的时候才会被特化,同样其成员函数也是在被使用的时候才被实例化。但是虚函数成员例外,原因应该是在定义一个模板类类型的变量时(使用模板类),为了确定虚函数表的大小,就已经实例化了虚...
  • sinat_35261315
  • sinat_35261315
  • 2016年11月11日 10:06
  • 955

模板类中可以使用虚函数吗?模板成员函数可以是虚函数吗?

内容转载自csdn论坛。 1,模板类中可以使用虚函数。 完全一样, 在非模板类里怎么用虚函数, 就在模板类里怎么用 template class class A { public:...
  • zzuchengming
  • zzuchengming
  • 2016年06月26日 17:26
  • 2207

C++笔记(继承,多态,虚函数,模板函数,异常捕获)

C++面向对象:1.继承//继承--子类继承父类(儿子继承爸爸),儿子有了爸爸的特性和财产,提高了代码的重用性.class A { public: void Func1(void); ...
  • ccj659
  • ccj659
  • 2016年09月05日 11:33
  • 494

纯C语言简单模拟C++的虚函数表

多态,面向接口编程等设计方法并没有绑定到任何特定的语言上,使用纯C也可以实现简单的多态概念。下面给出一个非常简单粗糙的例子,只为说明概念。 父类Animal定义 文件:animal.h#ifndef...
  • smstong
  • smstong
  • 2016年02月15日 18:14
  • 2474

成员函数模板不能为虚函数

#include #include using namespace std; template class A{ public: virtual void beep(){ } //成员函数...
  • qaz2549066580
  • qaz2549066580
  • 2015年02月28日 17:52
  • 676

娱乐,C语言模拟C++虚函数多态性。

看有感,原来C语言可以这样玩。。仔细想想,C++不也是在汇编层面上的封装么。膜拜这些语言设计者,深谙计算机科学的精髓,真是长见识了。本文只是简单模拟下多态,大体上就是C++的虚函数表机制,并没有考虑类...
  • shallwake
  • shallwake
  • 2009年12月05日 00:25
  • 3203

利用C++模板,代替虚函数,实现类的静态多态性

文章来源 http://www.cppblog.com/woaidongmao/archive/2008/05/22/50805.aspx 熟悉模板编程的朋友或许听到过这个技巧或者模式:Barton...
  • yangdelong
  • yangdelong
  • 2017年01月03日 11:09
  • 1004

为什么要用虚函数?什么时候用虚函数?

刚开始学C++学到“类”这一章的时候一直不明白虚函数用来做什么。看书上举的例子不太明白。 #include using namespace std; class Father { public: ...
  • CharlesSimonyi
  • CharlesSimonyi
  • 2013年04月16日 22:25
  • 5682
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用模板模拟虚函数
举报原因:
原因补充:

(最多只允许输入30个字)