时间:2021-05-20
泛型编程与面向对象编程的目标相同,即使重用代码和抽象通用概念的技术更加简单。但是面向对象编程强调编程的数据方面,泛型编程强调的是独立于特定数据类型。
这一篇介绍一下 C++ 编程中与面向对象并列的另一大分支——泛型编程,这一篇主要介绍函数模板、类模板和成员模板三大部分
如有侵权,请联系删除,如有错误,欢迎大家指正,谢谢
泛型编程
模板是泛型编程的一种重要思想,STL(Standard Template Library,标准模板库)是采用模板实现的一个实例
函数模板
对比函数重载(同一作用域内函数名相同,参数列表不同的函数),函数模板只需要一个函数就实现了函数重载的部分功能(参数个数相同类型不同,函数重载需要定义多个同名参数列表不同的函数)
函数模板具体化,函数模板具体化就是将某一(某几)个要处理的类型单独处理,需要单独写一个实现,形式是 template<> void fun(type& t);,函数模板的具体化和普通函数可以同时存在,调用顺序是 普通函数 > 函数模板具体化 > 模板函数
// ====== 测试一:函数模板针对特殊数据类型具体化 ======struct Node { int val; Node* next;};// 函数模板template<typename T> void tfunc(const T& t) { cout << "template: " << t << endl;}// 函数模板具体化(用于处理Node类型数据)template<> void tfunc<Node>(const Node& node) { cout << "template<Node>: " << node.val << endl;}// 函数模板具体化(用于处理int类型数据)template<> void tfunc<int>(const int& n) { cout << "template<int>: " << n << endl;}// 普通函数void tfunc(const int& n) { cout << "tfunc(): " << n << endl;}double d = 2.1;tfunc(d); // 函数模板未具体化double类型函数,调用模板Node node{ 2, nullptr };tfunc(node); // 函数模板具体化Node类型函数,调用函数模板的具体化int n = 2;tfunc(n); // 函数模板具体化int类型函数,也存在普通函数,调用普通函数// ====== 测试二:函数模板部分具体化 ======template<typename T1, typename T2>void tfunc(T1 t1, T2 t2) { cout << typeid(T1).name() << " and " << typeid(T2).name() <<": " << t1 << " " << t2 << endl;}template<typename T1>void tfunc(T1 t1, int i) { cout << typeid(T1).name() << " and " << "int: " << t1 << " " << i << endl;}template<typename T2>void tfunc(long l, T2 t2) { cout << "long and " << typeid(T2).name() << ": " << l << " " << t2 << endl;}template<>void tfunc(short l, int i) { cout << "long and int: " << l << " " << i << endl;}// 分别调用以上四个模板函数tfunc(char('c'), char('c'));tfunc(char('c'), int(10));tfunc(long(10), char('c'));tfunc(short(10), int(10));函数模板实例化,让编译器生成指定类型的函数定义,不用写函数的实现,形式是 template void fun(type& t);
// 函数模板template<typename T> void tfunc(const T& t) { cout << "template: " << t << endl;}// 函数模板实例化,不用写函数的实现,编译器会生成该类型的模板具体化函数template void tfunc<char>(const char& c);类模板
类模板可以指定默认模板参数(函数模板不可以),跟函数参数的默认值一样,必须从右向左连续赋值默认类型,如果实例化对象时又传递了类型,默认类型会被覆盖掉,跟函数参数是一样的
创建对象时需要传递模板参数列表,模板参数列表加在类名后面 ClassName< typename T > classN; 如果类的模板参数列
表有默认值,可以不传模板参数,但一定要加 <> 如 ClassName< > classN; 创建堆区对象的时候,所有的类名称后面都要加模板参数列表,如 ClassName< typename T >* classN = new ClassName< typename T>; 除了类内,其他地方出现 ClassName 的地方一般都要加模板参数列表
类模板的继承,类模板被继承后参数的传递方式主要有两种,一种是直接在子类继承父类的时候,为父类指定固定的类型,二是通过子类模板参数列表传递
// ====== 测试一 ======template<typename T, typename Y>class A {public: A(T t, Y y) { }};class Test : public A<int, double> { // 父类是类模板,子类是普通类public: Test() : A<int, double>(2, 2.1) { }};Test();// ====== 测试二 ======template<typename T, typename Y>class A {public: A(T t) { }};template<typename X, typename Z, typename P>class Test : public A<X, P> {public: Test(X x, Z z, P p) : A<X, P>(x) { }};Test<int, double, char>(int(2), double(2.1), char('a'));类模板的多态,在创建对象时,分为子类没有模板(CFather<short, char>*cf = new CSon;)和子类有模板(CFather<short, char> *cf = new CSon<short, int, char>)两种,子类和父类的模板参数列表可以不一样,但一定要对应好
类模板具体化,类模板的具体化分为部分具体化和全部具体化两种
template<typename T1, typename T2>class Test {public: Test() { cout << "T1 and T2" << endl; }};// 部分具体化template<typename T1>class Test<T1, int> {public: Test() { cout << "T1 and int" << endl; }};// 部分具体化template<typename T2>class Test<long, T2> {public: Test() { cout << "long and T2" << endl; }};// 全部具体化template<>class Test<long, int> {public: Test() { cout << "long and int" << endl; }};// 分别创建上面四个类Test<char, char>();Test<char, int>();Test<long, char>();Test<long, int>();成员模板
成员模板简单说就是模板中的模板
class Base1 { };class Base2 { };class Test1 : public Base1 { };class Test2 : public Base2 { };template<typename T1, typename T2> class Pair {public: T1 t1; T2 t2; Pair(T1 t1, T2 t2) : t1(t1), t2(t2) { } // 类模板中的成员模板 template<typename U1, typename U2> Pair(const Pair<U1, U2>& pair) : t1(pair.t1), t2(pair.t2){ }};Pair<Base1*, Base2*>(Pair<Test1*, Test2*>(new Test1, new Test2));如果未特殊说明,以上测试均是在win10 vs2017 64bit编译器下进行的
总结
以上所述是小编给大家介绍的C++ 泛型编程,希望对大家有所帮助!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
C++中函数重载、覆盖与隐藏详解在C++语言中,函数扮演着很重要的角色,不管面向过程设计,还是基于对象设计;不管是面向对象编程,还是基于泛型编程,函数都可以随处
本文针对C++函数模板与类模板进行了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解。具体内容如下:泛型编程(GenericProgramm
Template所代表的泛型编程是C++语言中的重要的组成部分,我将通过几篇blog对这半年以来的学习做一个系统的总结,本文是基础篇的第一部分。为什么要有泛型编
linux下的C\C++多进程多线程编程实例详解1、多进程编程#include#include#includeintmain(){pid_tchild_pid;
python网络编程详解网络编程的专利权应该属于Unix,各个平台(如windows、Linux等)、各门语言(C、C++、Python、Java等)所实现的符