范型编程杂谈

泛型编程的案例 php C C#等主流研发语言的泛型案例 立即下载
谈范型(GP)之前, 先谈一下面向对象(OO), OO强调世界是由对象组成的,对象是由方法和属性组成的(个人感觉还应该加上事件),而对象之间又有继承(is-a)和组合等 关系。OO很符合我们认识世界的直觉,它以封装,继承和多态为特性,我们在现实工作中又总结出来了OO的5大设计原则和23种设计模式。总之,OO基本上已经可以很好的解决我们现实生活中的所有问题。

那么既然OO已经可以很好的解决我们的问题了,为什么还要有GP? 

我们先来看一下OO的缺点:
OO的多态是通过继承自同一接口来实现的, 修改接口会导致所有派生类的修改,耦合比较紧密。
OO的多态是运行时的, 性能比较低。
OO的多态通过抽象接口实现,使用不安全,在不支持反射的语言(比如C++)中会丧失类型检测。 

用OO设计时,你只能通过抽象接口来处理不同的事物。比如你要让Cat和Dog同时跑动,你可能会抽象出一个IAnimal接口,内部有一个Run的方法,然后让Cat和Dog分别继承。但是如果你想让猫(Cat)和玩具猫(ToyCat)支持跑动,这时你抽象出IAnimal就不合适了, 你可能会抽象出ICatProperty。可以看到OO的这种继承体系非常笨重,到后面可能会导致非常深的继承层次(比如MFC),代码扩展和维护都很艰难。

上面OO的这些缺点在GP没有被发现之前都不是缺点,因为我们没有更好的解决方案,但是人们逐渐发现了GP,GP最初是在使用容器(Container)时被发现的,container<T>可以放任意类型的元素,根据元素类型,我们可以可以生成任意类型的container. 这些技术后来发展成范型编程和模板元编程。

那么什么是GP?
我的理解是 GP是基于concept的程序设计,我们通过concept来定义对象之间的关系。

什么是concept?
按我的理解,concept就是我们自己定义的概念和规则。

比如说任何对象,只要可赋值,他就符合Assignable的concept:
class  A {};
class  B {};

void  test()
{
   A a1; A a2; a1  =  a2;
   B b1; B b2; b1  =  b2;
}
上面的A和B就都符合Assignable的concept.

又比如任何对象,只要可比较, 他就符合Comparable的concept:
class  C
{
    public :
        bool  operator  <  ( const  C &  c);
        bool  operator  >  ( const  C &  c);
        bool  operator  ==  ( const  C &  c);
        bool  operator  !=  ( const  C &  c);
        bool  operator  <=  ( const  C &  c);
        bool  operator  >=  ( const  C &  c);
};
上面的对象C,他就符合他就符合Comparable的concept。

再看一个例子:
class  Dog 
{
public : 
    void  run();
};

class  Cat
{
public : 
    void  run();
};

template < typename T >
void  run(T &  t)
{
    t.run();
}
上面的Cat和Dog就都符合拥有成员函数Run这个concept.

GP的concept可以是任何我们能想到的规则,比如包含某个成员变量,或是定义某个类型, 比如下面代码:
class  myTraits
{
public :
   typedef  int  type;
   type value;
};

template < typename T >
typename T::type GetValue(T &  t)
{
    return  t.value;
}

甚至GP的concept可以是指明基类和派生类, 比如下面代码:

template < typename TDrived, typename TBase >
class  CMyImpl:  public  TBase
{
public :
      void  work()
   { 
      TDrived *  p  =  static_cast < TDrived *> ( this );
      p -> Hello();
     }
};

class  CMyBase {};
class  CMyClass:  public  CMyImpl < CMyClass, CMyBase >
{
public :
      void  Hello() {}
};
ATL中大量应用这种concept来实现代码重用和模拟虚函数。

这些concept在不同语言中定义不一样,在一些语言中(比如C#)我们可以通过定义来进行显式约束,表明我们某个concept要满足哪些条件;在有些语言中(比如C++)则没有这显式约束定义,我们只能通过我们编程时自己的逻辑来保证,当然如果某个方法要求他的对象满足某个concept而你的对象没有满足 ,编译器也是不会让你通过的。

另外GP的concept之间本身也有某种关系, 某个concept可能继承与另外一个concept,或者说某个concept是另外一个concept的强化,也就是满足某个concept的对象肯定也同时满足另外一个concept. 比如concept  A包含Run方法, concept B包含Run和Eat方法,则concept B是concept A的强化,满足concept B的对象肯定同时满足concept A。

我们可以看到GP的这种基于concept的设计方式,大大降低了对象之间的耦合性,我们不再要求象OO那样抽象出共同的接口来让大家继承;任何两个看似没有关系的对象, 只要他们满足某个concept的约束,他们就能当作模板参数传给GP代码(模板类或是模板函数)。另外,我们可以看到GP的这些类型检测是在编译时就完成的,他的多态是在编译时就确定的静多态, 效率大大高于OO的动多态。
 
有些人说GP的抽象能力高于OO,这个观点我并不认同,我感觉只是他们的抽象方式不一样,OO是基于接口, 而GP是基于concept。OO的基于接口的抽象,在源代码和最终运行时都能体现,源代码中是接口,运行时是虚表,所以他们是一致的, 符合普通人的思维习惯。GP基于concept的抽象, 主要体现在源代码中 ,只是你用来告诉编译器你的思维方式, 在运行时他可能是一个完全不同的世界,所以比较难理解。

如果说OO的设计是抽象出接口, GP的设计就是抽象出concept, 满足某个concept的class是一个template class(如template<typename T> class vector), 而template class的又可以实例化成某个特定的class(如vector<int>)。 所以GP可以大大减少我们源代码的数量,但是他本身不能减小我们最终编译的可执行文件的大小,相反如果模板类过大,反而会造成代码膨胀,而OO的继承则没有这个问题(可参考 C++模板会使代码膨胀吗 )。

对于在实际开发中主要用OO还是用GP的问题, 可能应人和公司而异,  最好的方式当然是OO和GP的灵活结合 。有人觉得GP的代码不好理解,那是因为你没有理解他的concept,比如看了《范型编程与STL》,你就会发现自己也可以扩展STL了。当然,因为C++对concept没有约束定义机制, 而concept这个东西注释又不好描述,所以大部分时候我们只能通过源代码来推理,这在一定程度上也造成了GP代码难读懂这种说法的流行。
高分辨率航拍图像的目标检测切图优化策略 本文深入探讨了高分辨率航拍图像目标检测中的切图优化策略。针对大尺寸图像直接缩放导致小目标信息丢失的问题,文章详细阐述了基于重叠切割的核心方法,包括如何根据目标尺寸确定切图尺寸与重叠率,并提供了从切图到坐标还原的完整代码实现与避坑指南,有效提升检测精度与效率。 阅读详情

相关推荐

MinerU与Docling:智能文档处理框架对比

本文对比分析了MinerU和Docling两大智能文档处理框架。MinerU专注于高精度PDF解析,采用多模态AI技术,在学术文献、金融报表等复杂文档处理上表现优异;Docling则定位企业级多格式文档处理平台,支持10+格式转换,更适合文档管理系统等场景。技术层面,MinerU基于VLM模型实现端到端处理,Docling采用插件化多后端架构。性能测试显示MinerU精度更高(95%+),但资源消耗较大;Docling处理速度更快(1-3秒/页),部署更灵活。

轩哥的个人研究和成长记录 1912

胡扯OO和泛型编程

看了几天Introduction to C++ for Financial Engineers,结合之前看的

Blaze the Way of Quantitative Trading 863

ICT调试技巧:从基础到实战的全面指南

本文提供了一份全面的ICT调试技巧指南,涵盖从基础认知到实战应用的全过程。详细解析了ICT设备硬件结构、程序文件构成,并重点讲解了调试界面的核心参数与高效快捷键。通过跳线、电阻、电容及二极管等常见元器件的实战调试案例,分享了参数设置要点与典型问题解决方案,帮助工程师快速掌握ICT调试核心技能,提升测试效率与准确性。

weixin_29202213的博客 342

泛型编程之模板

泛型编程        泛型编程是指编写与类型无关的逻辑代码,是代码复用的一种手段。进行泛型编程的基础是模板。 模板        这里的模板与我们生活中的模板类似,我们可以用一个模板产生非常多的实例,比如印刷试卷时,机器上用一个模板可以印刷成千上万张试卷,在这里我们也可以用一个模板来产生很多代码。        模板分类; 函数模板初介绍         一个函数模板代表着一种函

xuzhangze的博客 369

别再折腾SNAP了!ENVI 5.6.0 直接拖拽打开Sentinel-2 L2A数据的正确姿势

本文详细介绍了ENVI 5.6.0直接处理Sentinel-2 L2A数据的高效方法,无需通过SNAP进行繁琐的重采样预处理。通过直接拖拽XML文件,用户可以快速加载不同分辨率的波段数据,显著提升工作效率。文章还对比了直接打开与SNAP重采样流程的优劣,并提供了常见问题解决方案和高级应用技巧。

weixin_30296405的博客 635

手把手教你学Simulink--控制执行场景实例:基于Simulink的智能车辆自动紧急制动(AEB)仿真

本文完成了基于 Simulink 的智能车辆自动紧急制动(AEB),实现了:✅ 构建前车急刹与静止障碍物典型场景✅ 设计基于 TTC 的三级 AEB 决策逻辑✅ 验证在高风险场景下有效避免碰撞✅ 掌握从风险评估到制动执行的完整安全链✅ 为ADAS 主动安全功能开发奠定基础。

MHD0815的博客 237

泛型编程中三大模板类型(类模板、函数模板、成员模板)的应用—HJ-record10

类模板 函数模板 成员模板

恋蛩音的博客 430

FPGA实现CAN接口(SJA1000)

学无止境,善于积累,每天积累一点点,成功就在眼前,加油! 1 CAN总线简介 CAN(Controller Area Network,控制器局域网 )总线是一个多主机异步串行总线,也是国际上应用最广泛的现场总线之一。在现场总线中,它是惟一被ISO国际标准化组织批准的现场总线。由于其成本低、容错能力强、支持分布式控制、通信速率高等优点在汽车、工业控制、航天等领域得到广泛应用。特别是由于CAN总线具有...

m0_46498597的博客 1万+

泛型编程点滴之vector模板

组件 描述 容器(Containers) 容器是用来管理某一类对象的集合。C++ 提供了各种不同类型的容器,比如 deque、list、vector、map 等。 算法(Algorithms) 算法作用于容器。它们提供了执行各种操作的方式,包括对容器内容执行初始化、排序、搜索和转换等操作。 迭代器(iterators) 迭代器用于遍历对象集合的元素。这些集合可能是容器,也可能是容器的子集。 ...

wangsongzxcvbnm的博客 655

AgentScope实战训练营- Java从零开始快速构建Agent完整教程

本文基于阿里巴巴开源的 AgentScope Java 框架,从零开始手把手带你构建 AI 智能体应用。内容涵盖环境搭建、基础对话、工具调用、结构化输出、多Agent流水线、Hook可观测性、会话持久化、MCP协议、RAG知识库集成、多模态工具、技能系统、Spring Boot Web部署等21个核心模块,附带完整可运行代码示例,帮助Java开发者快速掌握Agent开发全流程。

program哲学 863

Multisim14.0仿真应用设计(十六)74LS138译码器应用仿真

74LS138为3线-8线译码器。

zhusl6688的博客 2982

《Effective C++》笔记与杂谈——条款01

C++并不是一个单一的语言,而是一个语言联邦,由四个次级语言组成,每个次级语言都有自己的规约。记住这四个语言你就会发现C++容易了解得多。

Yu_Lijing的博客 367

Android 13 Settings蓝牙列表卡顿问题排查及优化过程

此时我们的卡顿优化基本完成了,我们应该要考虑内存是否会泄漏,如果大家不知道哪些需要回收可以用leakcanary和android profiler进行内存检测,看代码有没有内存泄漏。

龚礼鹏的博客 2547

Spring杂谈(全面的总结)

前言: 最近一直在学习spring,写这篇文章的目的出于对近期所学做一个总结,最主要的也是希望让大家重新认识下spring.讲到spring大家都会想到Ioc.,Ioc字面意思是控制反转。不知道大家小时候有没有一个习惯遇到不认识的单词先查新华字典。其实当我们遇到不认识的语句时可以查查维基百科英文版,看看它给出的解释.下面是维基百科对Ioc的解释。 Insoftware engineering,inversion of control(IoC) is a programming principle....

dajunstan的博客 216

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

杂谈面向对象方法论

不可否认,“映射(或称变换)”是科学技术中一类极为重要的方法,计算的本质即映射,往再深处说,运动的本质也是映射--对某系统的状态进行时空变换。 图灵机作为一种经典的计算模型,揭示了机械计算的一种方法,对数据(构成图灵机模型的七元组中的输入及状态)进行运算然后输出,基于图灵机的计算机直到今天都遵循着这样的运作机理,计算机其实就是一台可对其指令进行编程的机器。 两大核心:数据与指...

天云创意 276

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

杂谈---2013年,总结?吐槽?灌水?

引言     最近看到不少猿友都纷纷总结起自己的2013年,LZ也赶赶热潮,对自己一年的收获与失去来个大阅兵,这确实有助于自己来年的规划。如果各位猿友不喜欢写博客,也应该以其它的方式对自己进行总结,相信总是有好处的。至于LZ,已经习惯了博客,因此就暂且采取这种方式了。不过LZ也只是让手指在键盘上随心而动,所以难免是水文一篇,各位猿友尽可一笑而过。   技术方面      既然是一个技术

Java's paradise 901

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Swift学习笔记

Swift学习笔记 在网上没有找到过最新的Swift笔记。 在此立下一个flag,写下自己学习Swift学习笔记。如有错误请指正。 文章目录 最开始的话 Swift基础语法。 Swift基础数据类型 Swift字符串 Swift运算符 Swift流程控制 Swift集合类 Swift进阶教程 Swift函数 Swift闭包 Swift范型 Swift多线程 Swift面形对象编程 Swi...

weixin_42184286的博客 262

《七周七语言》读后感

在微博上看到Robbin老大推荐《七周七语言》一书,去豆瓣上查了一下发现大家对这本书的评价也是非常高,于是就想着去读一下。书买了之后由于找工作一直没有来得及看,随着前段时间把工作定了,就着手对这本书的学习了。从书名来看,顾名思义就是讲了七种不同的编程语言。自己浏览了一下目录,心里也大致衡量了一下,对于这七种语言,我觉得我以后会用到的或者说是能去学的应该...

weixin_33814685的博客 130

技术概念规范

技术概念规范 更多请见个人主页https://www.bajins.com 目录技术概念规范flag编程范式设计模式及原则数据结构与算法算法复杂度数据传输模型网络通信协议HTTPswitchdirectory和folder区别进制逻辑运算符字符编码Cron表达式命名规范GNU风格版本规则多线程线程数量控制缓存锁和事务HTTP授权认证OAuth2和JWT区别与联系加密哈希 flag 代码不是靠死记硬背,而是不停的写、不停的思考,在反复的练习中熟练掌握的。 编程需要学习记住的是:不同的场景中一些实现方式的原理

Claer_XX的博客 906

Java基础:Java语言简介

本文介绍了java语言的发展史、概念、特点。

love_study1314的博客 736

常见体系结构介绍

常见体系结构介绍 数据流系统 概念:以算法和数据结构为中心, 像管道和过滤器般处理数据,每个组件都有相对独立的数据处理功能,数据依次经过各个组件,最后形成完整的数据处理系统。 优点:各个组件都是独立的, 可以放方便的组合、重用和扩展,流水线式的执行,支持大规模并行处理。 缺点:流水线式的处理, 所以一般要求数据有比较统一的输入和输出格式;各个组件都是独立的, 因此的很难提取共性;批处理

quasiceo 1122

MFC 知识点6

泛型编程就是用独立于任何特定类型的方式编写代码,所以简单地说,类是对象的抽象,而模板又是类的抽象,也就用模板能定义出具体类.类模板类模板的使用实际上是将类模板实例化成一个具体的类,它的格式为:类名&lt;实际的类型&gt;。类模板的派生可以从类模板派生出新的类,既可以派生类模板,也可以派生非模板类。派生方法:⑴ 从类模板派生类模板可以从类模板派生出新的类模板,它的派生格式如下例所示:  templ...

哲学天空的博客 269

MFC,ATL,WTL的历史沿袭

需求推动了技术的发展,从MFC到ATL,从ATL再到WTL的发展历程我想就是一个最好的见证。 早期的VC++开发者们发现了MFC(Microsoft Foundation Classes) 这样一个好东东。他们发现,MFC提供了一个强大的类库,很好的满足了面向对象编程的需要。随着泛型编程技术的发展和时间的推移,慢慢地,他们慢慢觉得MFC的类库过于庞大和宽泛,而且它提供的模板库只覆盖了很有限的

numbibi的专栏 1491
上一篇: 软命令接口的适用场合
下一篇: 一个优秀windows C++程序员的知识体系
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值