c++泛型为什么存在?

  c++作为一种从c演变过来的并且采用了面向对象理念的半面向过程半面向对象的编程语言,在c的显式转换和隐式转换的基础上,也有自己的类型转化方式。在具体讨论c++的类型转换之前,首先来了解一下其中用到的重要的技术思想-泛型。

  还是首先来举一个老生常谈的例子,写一个比较两个数据对象大小的函数,如果不出意外的话,可能至少有以下几个:

   1 int cmp(int a,int b);

   2 double cmp(double a,double b);

   3 double int cmp(int a,double b);

   4 int cmp(char a,char b);

   5 int cmp(const A & a,const B & b); (A,B is a class)

  我们知道在c++或java(c不支持函数重载)里面有重载机制,允许函数名称相同,参数个数和参数类型不同。

  c是如何解决"函数重载"问题的呢?宏机制。比如以上问题,我们可以编写以下宏:

   6 #define Min(x,y) ((x)<(y)?(x):(y))

  但是宏机制有什么问题呢?

  宏的第一个问题就是不检查类型,无法在编译期间检查程序错误,比如一个自定义对象和一个整数进行Min操作;

  第二个问题就是宏只是进行单纯的文本替换,因为优先级问题,宏很容易出现错误结果。

  但是即使是函数重载,它的缺点是显而易见的:

  代码冗余。这四个函数的逻辑是一致的,但是却又四个版本。  

  另外一个问题,相似类的定义问题。

  c++内建的几种数据类型(int double),如果我们想建立一个数组的话,使用标准模式:  class A [max] 或者  class A* =new A[max];  如果是自定义的类,并且这样的类千变万化,我们就需要一种机制来解决相似类的重复定义问题,降低编程工作量。

  还有一个问题,型式兼容性问题。

  一 . 从型式转换角度看

  c里面的类型转化:(T)x

  1.内建型式(int double)对象转换安全性基本保证

  2.类对象之间的转换可能导致无法控制的结果

  c++型式的转换:T(x)

  1.可能需要单参数构造函数和重载的型式转换操作符

  2.如果未实现 转换就不存在

  二 . 从类库架构上看

  根据类的继承层次,需要频繁的进行对象的型式转换,比如基类的指针或者引用指向子类,或者子类转换为父类

  但是已有的c/c++型式转换均为静态转换,不能适应指针或者引用的多态性

  所以 我们就需要一种机制来保证型式兼容,这种机制必须具有以下特点:

  1.确保型式转换合法有效,并且在失败时通知用户

  2.需要维持对象的运行时型式信息(run-time type information,RTTI)

  以上,就是泛型存在的价值:函数重载问题 相似类定义问题 型式兼容性问题。

  泛型的具体实现方式--模板和型式参数化在下篇文章介绍。

时间: 2024-10-18 11:34:26

c++泛型为什么存在?的相关文章

.NET编程01(泛型)

一:Object 类型:一切类型的父类,通过继承,子类拥有父类一切属性和行为:任何父类出现的地方,都可以用子类来代替: 用一个方法来完成多个方法做的事 /// <summary>    /// 普通方法类    /// </summary>    public class CommonMethod    {        /// <summary>        /// 打印个int值        /// </summary>        /// <

c#系统泛型委托

Action<T> 无返回值的系统泛型委托 namespace ConsoleApp1 { public class UserInfo { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } class Program { private static List<UserInfo> getInit() { return new List<User

泛型2

万用字符(wildcard) 以动物Animal类为例,怎样才能创建出一种ArrayList<?>里面既可以保存ArrayList<Dog>,又可以保存ArrayList<Cat>? public void takeAnimals(ArrayList<? extends Animal> animals){  //泛型中extends同时代表继承和实现. for(Animal a : animals){ a.eat(); } } 我们可以这样调用该函数: Ar

通过反射了解集合泛型的本质

通过反射了解集合泛型的本质 import java.lang.reflect.Method; import java.util.ArrayList; /** * 通过反射了解集合泛型的本质 * @author shm * */ public class MethodDemo02 { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("hello"); list.add(

构造方法中使用泛型

------------siwuxie095 构造方法中使用泛型: 构造方法可以为类中的属性初始化,如果类中的属性通过泛型指定,而又需要 通过构造方法设置属性内容的时候,构造方法的定义与之前并无不同,不需要 像声明类那样指定泛型 package com.siwuxie095.generic; class Context<T>{ private T value; public Context(T value) { this.value=value; } public T getValue() {

泛型委托当参数传递

假如有一个Person类: public class Person { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } public string Title { get; set; } } 执行一个方法: /// <summary> /// 传递一个泛型委托方法 /// </summary> /// <param name="acti

类库,委托,is和as运算符,泛型集合

类库:其实就是一堆类文件,只不过用户看不到这些类的源代码,保密性好. 优点:保密性好缺点:如果这个方法不好用,使用者无法自己去更改它. 类文件是.cs    类库是.dll 新建项目为类库,在debug文件夹下找到dll文件 委托:委托可以理解为:函数的指针 关键词:delegate 声明委托类型:public delegate int FirstDel(int a, int b); FirstDel不是类,是委托变量,不能实例化(不能new), 创建委托变量:FirstDel 名字 = 与这个

泛型委托

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace 泛型委托 { public delegate int DelCompare<T>(T t1, T t2); // public delegate int DelCompare(object o1, object o2); class Progra

java 16-8 泛型高级之通配符

泛型高级(通配符) ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了 ? extends E:向下限定,E及其子类 ? super E:向上限定,E极其父类 1 import java.util.ArrayList; 2 import java.util.Collection; 3 public class GenericDemo { 4 public static void main(String[] args) { 5 // 泛型如果明确的写的时候,前后必须一致 6 C

蓝鸥Unity开发基础二——课时21 泛型

本节课我们来学习C#中的泛型,泛型是一个特殊的类型,它可以最大限度的重用我们的代码! 推荐视频讲师博客:http://11165165.blog.51cto.com/ 使用泛型能够最大限度的重用代码,保护类型安全,提高性能 泛型成员因为类型的不确定性,不能使用算术运算符,比较运算符 类型参数可以有多个,可以是编译器能够识别的任何类型 类型参数的名字不能够随便起,不能重名 一.数组类Array using System; namespace Lesson_21{    //数组类Array