浅谈C++中的泛型编程

    xiaoxiao2021-03-25  96

    一、概述

    泛型(Generic Programming)即是指具有在多种数据类型上皆可操作的含 意。所谓泛型编程,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。上面所叙述的是函数模板,实际上模板分为函数模板和类模板。类模板与函数模板的定义和使用类似,有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同,所以将类中的类型进行泛化。

    二、模板的形式

    1、函数模板语法格式

    template<typenam T> template<class T> ------------------------------------- template<typename 类型参数表> 返回类型 函数模板名(函数参数列表) { 函数模板定义体 }

    2、类模板的语法格式

    template<typename T> class A{}

    template是语义是模板的意思,尖括号中先写关键字 typename 或是 class ,后 面跟一个类型 T,此类即是虚拟的类型。至于为什么用 T,用的人多了,也就是 T 了。

    三、函数模板细化和模板案例

    1、模板函数小案例

    #include <iostream> using namespace std; template<typename T> void swap(T &a, T &b) { T t = a; a = b; b = t; } int main() { int x = 10; int y = 20; cout << "int型交换前" << endl; cout << "x=" << x << "y=" << y << endl; swap<int>(x, y); cout << "int型交换后" << endl; cout << "x=" << x << "y=" << y << endl; float e = 1.1; float f = 2.2; cout << "float类型交换前" << endl; cout << "e=" << e << "f=" << f << endl; swap <float>(e, f); cout << "float类型交换后" << endl; cout << "e=" << e << "f=" << f << endl; return 0; }

    总结:函数模板,只适用于函数的参数个数相同而类型不同,且函数体相同的情况。如果个数不同,则不能用函数模板

    2、函数模板与函数重载
    #include <iostream> using namespace std; template <typename T> void swap(T &a, T &b) { cout << "我是模板函数" << endl; T t = a; a = b; b = t; } void swap(char &a, int &b) { cout << "我是普通函数" << endl; int t = a; a = b; b = t; } int main() { char cData = "a"; int iDate = 10; swap(cData, iDate); swap(iDate, cData); swap<int>(iDate, cData); return 0; }

    总结:普通函数会进行隐士的数据类型转换, 函数模板不提供隐式的数据类型转换必须是严格的匹配。当函数模板和普通函数都符合调⽤用时,优先选择普通函数,若显⽰示使⽤用函数模板,则使⽤用<>类型列表。如果 函数模板产⽣生更好的匹配使⽤用函数模板。

    3、模板编译机制总结

    编译器并不是把函数模板处理成能够处理任意类的函数编译器从函数模板通过具体类型产生不同的函数编译器会对函数模板进行两次编译,在声明的地方对模板代码本身进行编译;在调用的地方对参数替换后的代码进行编译。

    四、类模板细化和模板案例

    1、一个简单的类模板小案例

    #include <iostream> using namespace std; template<typename T> //template<class T> class A { public: A(T tt) { this->t = tt; } T &getT() { return t; } private: T t; }; int main(void) { A<int> a(100); cout << a.getT() << endl; return 0; }

    总结:在类模板前应该用template<typename T>或者template<class T>来声明。

    2、模板类的派生

    #include <iostream> using namespace std; template<typename T> class A { public: A(T tt) { this->t = tt; } private: T t; }; //模板类派生普通类 class B : public A<int> { public: B(int t, int ii) : A<int> a { this->ii = i; } void printB() { cout<< "i:" << i <<endl; } private: int i; } //模板类派生模板类 template <class T> class C : public A<T> { public: C(T jj, T t) : A<T> t { this->jj = j; } void printC() { cout << "j:" << j <<endl; } private: T j; };

    总结:子类从模板类继承的时候,需要让编译器知道⽗父类的数据类型具体是什么(数据类型的本质:固定⼤大⼩小内存块的别名)A<int>

    转载请注明原文地址: https://ju.6miu.com/read-9750.html

    最新回复(0)