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

C++模板元编程详细教程(之十一) 《C++模板元编程详细教程》系列的第11篇,也是完结篇,主要介绍了visit的实现方法、C++的模板范式,以及一些Q&A和感悟 阅读详情

转自:http://blog.youkuaiyun.com/nancy_m/article/details/8691681


熟悉模板编程的朋友或许听到过这个技巧或者模式:Barton-Nackmann 技巧或者称 奇异循环模板模式(Curiously Recurring Template Prattern)。
     其实在 《c++ 编程语言》这本bible 书里,在模板那章提到过一个很奇妙的类的实现,用的就是这个技术。当时,我就被C++模板技术叹为观止。近期在学boost库时偶然碰到了这个技巧,同时在写一个类时引发了我的思考,这里就利用这个技巧来实现,静态多态函数(我自己发明的叫法,呵呵)。
 我们知道C++的多态函数会带来很多灵活性,但是不可避免的它是有运行时的性能损失的。 而c++的另一个强大特性就是模板了。模板给C++带来了,编译时的多态,通过模板元编程,C++可以实现类似C#,java的refection的特性。这里我就举来实现利用模板来代替虚函数。
 例子1:

#include <iostream>
using namespace std;
 
class common_base
{
public:
  virtual void fun()=0;
};
class common_derive:public common_base
{
public:
  void fun()
  { cout<<"in common_derive fun()"<<endl;
};
 
void main()
{
  common_base * pb = new common_derive;
  pb->fun();
}

  这是一个最普通的多态例子,下面看看一个比较有意思的例子:
例子2:

template<typename T>
class class1
{
public:
    class1(T t):m_val(t){}
    virtual T getVal(){
        cout<<"in class1,val =="<< m_val <<endl;
        return m_val;
    }
private:
    T m_val;
};

class derived: public class1<int>
{
public:
    derived(int i):class1<int>(i){}
    int getVal()
    {
        cout<<"in derived"<<endl;
        return class1<int>::getVal();
    }
};

template<typename T>
class derived2: public class1<T>
{
public:
    derived2(T val):class1<T>(val){}
    T getVal()
    {
        cout<<"in derived2"<<endl;
        return class1<T>::getVal();
    }
};

void main()
{
    class1<int> * pbase = new derived(10);
    pbase->getVal();

    class1<int> * pb2 = new derived2<int>(10);
    pb2->getVal();
}

这个例子我的用意是说明:模板类的虚函数多态,而且派生类可以有两种选择,一个实现为普通类,继承的是模板基类的特化类,一个就实现模板类(如 derived2)。很明显模板继承类有着普通类不可比拟的灵活性。

下面是这篇文章的重头戏了,也是本文的目的所在。
我们看到例子1,2都采用虚函数来实现多态,这个是一般选择,如何用模板来实现多态,而不是虚函数呢?
看这个例子:

template<class derive>
class base
{
public:
    void print()
    {
        derive::print();
    }
    void m_print()
    {
        downcast()->derive::m_print();
    }
protected:
    inline derive * downcast()
    {
        return static_cast<derive *>(this);
    };
    inline const derive * downcast()const
    {
        return static_cast<const derive *>(this);
    };
};

class der:public base<der>
{
public:
    der(int foo):_foo(foo){}
    static void print()
    {
        cout<<"in der print"<<endl;
    };
    void m_print()
    {
        cout<<"in der member fun m_print"<<endl;
        cout<<"has member foo="<<_foo<<endl;
    }
private:
    int _foo;
};

template<class base>
class der2:public base
{
public:
    static void print()
    {
        cout<<"in der2 print"<<endl;
    };
    void m_print()
    {
        cout<<"in der2 member fun m_print"<<endl;
    }
};

class tmpclass
{
public:
    void test()
    { cout<<"in test"<<endl;}
};

int main(int argc, char* argv[])
{
    //模板实现虚函数多态
    base<der> * pb= new der(100);
    pb->print();
    pb->m_print();

    //动态继承
    der2<tmpclass> d2;
    d2.print();
    d2.m_print();
    d2.test();

    return 0;
}

运行结果:

in der print
in der member fun m_print
has member foo=100
in der2 print
in der2 member fun m_print
in test

哈哈,看class der是不是同样实现了多态??而且语义和虚函数一致。可以进一步提取downcast()部分到一个基类实现更普遍的写法。

后面我实现了一个动态继承的类der2,它同样提供了灵活的继承用法,可惜好像因编译器而定,在vc6环境下是不能通过编译的,而在g++下是ok的。


C++ 中多态的实现原理-虚函数表详解 编译时多态(Compile-time Polymorphism):也称为静态多态性,是在编译时确定的多态性。C++中的函数重载和模板(Templates)是编译时多态的例子。函数重载允许定义多个同名函数,但它们的参数列表不同,编译器根据参数类型或个数来决定调用哪个函数。模板允许编写通用的代码,以适用于不同类型的数据。运行时多态(Run-time Polymorphism):也称为动态多态性,是在运行时确定的多态性。C++中的虚函数和继承是运行时多态的例子。 阅读详情

相关推荐

C++:继承(3)——多态:静态联编(重载、泛型)、动态联编(虚函数)

文章目录静态联编与动态联编静态联编的多态——根据指针类型确定执行方法静态联编的多态——泛型编程 模版动态联编的多态——虚函数参考链接 多态(Polymorphism)按字面的意思就是“多种状态”。   在面向对象语言中,接口的多种不同的实现方式即为多态。   引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技术,赋值之后,父对象就可以根...

weixin_41442027的博客 798

C++模板类与继承

C++模板类与继承

Crush_66的博客 4312

一个AI Agent顶十个软件,toB赛道正在大洗牌

一个AI Agent顶十个软件,toB赛道正在大洗牌

ith321的博客 1330

C++ 深入理解模板实现多态思想

本文主要详解C++中如何用模板来实现多态的特性

余识- 2134

手机拍视频就能训练机器人?SpatialLM开源模型实战指南(附HuggingFace部署教程)

本文详细介绍了如何利用开源模型SpatialLM通过手机视频训练机器人理解3D空间结构。从HuggingFace部署、视频预处理到模型推理和结果可视化,提供完整的实战指南,特别适合具身智能领域的开发者快速上手。

2y3u4i5o6p的博客 787

2025使用VM虚拟机安装配置Macos苹果系统下Flutter开发环境保姆级教程--下篇

我们可以看到,目前配置基本完成了,现在有两个错,一个是Chrome没安装,这个自己安装就可以了,如果不需要WEB测试也不影响开发,另一个是Simulator还没安装,这个主要是安装的时间太长了,也就是上面的这一步。这里要注意,这个下载安装会比较慢,有的载会特别卡造成安装失败,最好的办法是挂一个VPN,保证安装完成,不过这个可以在以后单独进行安装。至此,基本的安装完毕,好多人会以为Xcode就OK了,其实还没有,我们还缺少命令行工具包,这个在安装完Flutter以后进行设置。

weixin_48803304的博客 1411

平行世界用c++模板代替继承和包含关系

现实的c++程序挺让人无奈的,很多人喜欢重构,重写,没有积蓄,原因是新的方法和新的class等等不断填充代码,这一点其实确实不如像java,go,node一样。c++依然在于他的高效,其发展也很快,是一个良好的工具。比如我们写了一个Path类后面需求增加,变动,我们增加了hash类这时候麻烦的事情来了,我们要组合的时候,是包含还是继承,重新封装还是新建类作为两个类的包含者,方法很多,写的时候可能会经常改。可以看出,没有继承和包含等等关系,我们在使用的时候比较清楚,是平行的。...

qianbo042311的博客 563

关于DHCP Option60的认识

<br />       最近在网络建设过程中,必须面对一个实际存在的问题:当只有一根线入户时,该如何解决CATV和宽带业务的共存呢?这时就要考虑用到DHCP Option60了,那么DHCP Option60到底是如何来实现业务区分的呢?<br />首先先来看下DHCP协议,在DHCP协议中,定义了一个option字段,该字段主要是用来扩展DHCP协议的,Option 60 (Vendor class identifier)是DHCP报文中的一个选项字段,code为60,可以标识终端类型,根据不同的终

luoyingchuan的专栏 7940

java 模板实现静多态_利用C++模板,代替虚函数实现类的静态多态性及动态继承...

熟悉模板编程的朋友或许听到过这个技巧或者模式:Barton-Nackmann技巧或者称奇异循环模板模式(Curiously Recurring Template Prattern)。其实在《c++编程语言》这本bible书里,在模板那章提到过一个很奇妙的类的实现,用的就是这个技术。当时,我就被C++模板技术叹为观止。近期在学boost库时偶然碰到了这个技巧,同时在写一个类时引发了我的思考...

weixin_32110907的博客 205

Altera下载器驱动配置:手把手教程(从零实现)

详解Altera USB-Blaster驱动安装全过程,从设备识别到软件配置一步一图,解决常见连接问题,确保开发下载器正常工作,适合初学者快速上手FPGA下载调试。

weixin_35751194的博客 986

Vivado2023.2与Vitis协同开发:从Hello World到BOOT.BIN的完整流程解析

本文详细解析了使用Vivado 2023.2与Vitis协同开发ZYNQ/MPSoC平台的完整流程。从环境安装、硬件设计、软件编写、在线调试到生成独立的BOOT.BIN启动文件,手把手指导开发者完成从Hello World到系统固化的全步骤,并提供了常见问题的避坑指南,帮助初学者快速掌握软硬件协同开发的核心技能。

weixin_29197051的博客 176

C++之多态性

1.初探多态性 在面向对象方法中,所谓多态性就是不同对象收到相同消息,产生不同的行为。在C++程序设计中,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,这样就可以用同一个函数名调用不同内容的函数。换言之,可以用同样的接口访问功能不同的函数,从而实现“一个接口,多种方法”。 事实上,在程序设计中经常会使用到多态性。最简单的例子就是运算符了,例如我们使用运算符+,就可以实现整型数...

studyhardi的博客 5万+

Labelme安装教程(附Anaconda安装教程)

本文详细介绍了如何安装Anaconda和Labelme,还提供了常见问题的解决建议。

HanYan_ing的博客 1万+

C++ 虚函数与多态性

多态性 面向对象程序设计中的多态性是指向不同的对象发送同一个消息,不同对象对应同一消息产生不同行为。在程序中消息就是调用函数,不同的行为就是指不同的实现方法,即执行不同的函数体,也可以这样说就是实现了“一个接口,多种方法” ...

Chroniccandy的博客 2512

4、硬件工程师笔试面试知识器件篇——电阻(2025版本)

本文系统介绍了电阻的基础知识与应用。首先阐述了电阻的定义、工作原理及类型(固定/可变电阻),详细说明了常见电阻材料(碳膜、金属膜、线绕等)的特性与标记方法。重点分析了电阻在电路设计中的关键参数:功率计算需考虑1.5-2倍安全裕度,温度系数影响电路稳定性。文章还对比了不同封装形式(轴向/贴片/功率封装等)的适用场景,特别强调高功率电路需选择专用封装并做好散热设计。最后指出电路仿真可优化电阻选择,并列举了相关电子元件在设计中同样需要仿真验证。全文为硬件工程师提供了电阻选型的实用指导。

XU157303764的博客 5202

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

解释 C++ 中的多态性,以及如何实现运行时多态性?

然后,在基类指针或引用指向派生类对象时,调用虚函数会根据对象的实际类型而不是指针或引用的类型来确定调用的函数版本。编译时多态性:编译时多态性是通过函数的重载和模板实现的。在main函数中,基类指针ptr分别指向了Dog和Cat对象,但调用speak()函数时会根据指向的对象类型而执行不同的实现,这就是运行时多态性的体现。这意味着通过相同的接口可以调用不同类型的对象,并且会根据对象的实际类型来执行相应的操作。C++中的多态性通过虚函数来实现,分为编译时多态性(静态多态性)和运行时多态性(动态多态性)两种。

qiuyehuanghun的博客 3271

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【第五节】C++的多态性与虚函数

面向对象程序设计语言的三大核心特性是封装性、继承性和多态性。封装性奠定了基础,继承性是实现代码重用和扩展的关键,而多态性则是功能的扩充。多态性体现在对不同类的对象发送相同的消息时,会产生不同的行为。这里所说的消息主要是指对类成员函数的调用,而不同的行为则对应着不同的实现方式。在C++中,实现多态性的方法包括:函数重载运算符重载模板虚函数函数重载是多态性的一种基本形式,它允许在同一作用域内,相同的函数名对应不同的实现。函数重载的实现条件是函数参数的类型或个数必须有所区别。

攻城狮7号的博客 1418

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C++静态多态与动态多态

多态按字面的意思就是多种形态,相同的方法调用,但是有不同的实现方式。多态性可以简单地概括为“一个接口,多种方法,实现接口与实现的分离。 C++有两种多态形式:静态多态:也称为编译期间的多态,编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用那个函数,如果有对应的函数就调用该函数,否则出现编译错误。 静态多态有两种实现方式: 函数重载 函数重载就像是有多种含义的动词。例如:你可以在棒球场为球队助威(root),也可以在地里种植(root)菌类植物。 根据上下文可以知道每

路过的熊的博客 4224

C++ 多态性有哪些

C++多态性有哪些?       概念:指相同的对象收到不同的消息或者不同的对象收到相同的消息时产生的不同的实现动作。 C++支持两种多态:编译时多态(静态)、运行时多态(动态) (1)编译时多态:就是在编译期确定的一种多态。在C++中主要体现在函数模板,这里需要注意,函数重载和多态无关,很多地方把函数重载误认为是编译多态,这是错误的???      举例说明一下函数模板是如何体

YF_Li123的博客 1万+

C++多态、虚函数、虚函数表、编译期、运行期、静态、动态的理解

关于C++多态1. 多态分为静态多态和动态多态1.1 静态多态1.1.1函数重载1.1.2模板1.1.3静态多态总结1.2 动态多态:在运行时期才能决定函数行为1.2.1先讲一些储备知识,不然初学者听着迷糊1.2.2 多态的体现:1.2.3 动态的体现 1. 多态分为静态多态和动态多态 1.1 静态多态 静态多态是编译期决定的:在编译期间就决定了行为,也就是在运行到静态多态的时候函数的执行流程都一样 包括两种:函数重载和模板 1.1.1函数重载 函数重载:函数名相同且参数列表不同称为函数重载 静态多态体现

Go_bro的博客 2002

为什么析构函数必须是虚函数?为什么默认的析构函数不是虚函数?

微信搜索“编程笔记本”,获取更多信息 ------------- codingbook2020 ------------- 今天我们来谈一谈面试 C++ 工程师时经常被谈到的一个问题:为什么析构函数必须是虚函数?为什么默认的析构函数不是虚函数? 首先,我们看一下百度百科对虚函数是怎么定义的: 在某基类中声明为 virtual并在一个或多个派生类中被重新定义的成员函数,用法格式为:virtual...

qq_42247231的博客 2万+

学霸带你游戏化掌握 C++ 虚函数与多态性

多态性是面向对象编程中的一种特性,允许不同的对象以相同的接口表现不同的行为。换句话说,多态性让同一个方法可以作用于不同的对象。《黑暗之魂 III》(Dark Souls III)在《黑暗之魂 III》中,敌人和玩家角色的行为都可以通过相同的接口来进行控制。例如,攻击动作对玩家和敌人都适用,但具体表现会根据对象类型不同而有所不同。public:public:public:上述代码展示了通过多态性,函数能够处理Player和Enemy对象,尽管它们的攻击方式不同。

纽雪澳诺加海美德的博客 1284

【Cpp筑基】五、类的继承、虚函数、抽象基类

Cpp系列笔记目录。

Shen Mu Xin's Blog 1443

C++ 模板基础知识——多态在模板中的应用

在C++中,模板和多态是两种强大的编程技术,它们可以用来创建灵活和可重用的代码。虽然多态通常与继承和虚函数(动态多态)关联,但在模板中使用时,主要涉及到编译时多态(静态多态)。

慢慢记录,慢慢更新。 1681
上一篇: C#中的泛型
下一篇: C# IEnumerable 与 IEnumerator
骑行的蜗牛
博客等级 码龄21年 107粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值