IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++模板 -> 正文阅读

[C++知识库]C++模板

模板:将类型当作未知量,可以忽略类型的影响,从而减少类型对代码的影响

函数模板:

#include<iostream>
#include<string>
using namespace  std;
//单个位置类型
template<typename _Ty> //_Ty可以修改为任意
_Ty Max(_Ty a, _Ty b)
{


    return a > b ? a : b;//经典的冒号问号表达式
}
//多个未知类型
template<typename _Ty1, typename _Ty2 >
void print(_Ty1 a, _Ty2 b)
{

    cout << a << endl;
    cout << b << endl;
}
int main() 
{  
   int a=Max(1,3);
   cout << a << endl;
    print(1,2);
    print(1.1, 2.1);


}

调用方式:隐式调用 显式调用

函数模板两种形态 普通函数当作模板,类的成员函数当作模板

函数模板的特殊写法:缺省写法,存在常量的写法

#include<iostream>
#include<string>
using namespace std;
template <typename _Ty>		//告诉编译器 下面代码用到一个位置类型叫做_Ty
_Ty Max(_Ty a, _Ty b)
{
    return a > b ? a : b;
}
//在新标准中 typename_Ty 可以写成class _Ty
template <class _Ty1, class _Ty2>
void print(_Ty1 one, _Ty2 two)
{
    cout << one << endl;
    cout << two << endl;
}
class Fox
{
public:
    template<class _Ty1>
    void  printf(_Ty1 data=)
    {
        cout << data << endl;
    }
    template<class _Ty1>
    void printfdata(_Ty1 data);//类中声明
protected:
    string  name;
    int age;
};
//在类外实现不能省略template
template<class _Ty1>
void Fox::printfdata(_Ty1 data)
{
    cout << data << endl;
}
//缺省写法
template <class _Ty1,class _Ty2=int >
void printf(_Ty1 a, _Ty2 b)
{
    cout << a << b << endl;
}
//常量写法
template <class _Ty1, size_t size=3 >//size_t无符号整形
void printArray(_Ty1 array)
{
    for (int i = 0; i < size; i++) {
        cout << array[i];
    }
    cout << endl;

}
void test() //测试函数

{

    printf("狐狸",3544);//隐式调用
    printf<string>("狐狸", 123);//显式调用,虽有两个未知参数,由于缺省写法,可以少写一个类型,但参数个数不能少
    int array[3] = { 0 };
    //没有缺省必须显示调用
    printArray<int*, 3>(array);
    //有了缺省之后可以隐式调用
    printArray(array);
    //函数模板无法传入变量,函数参数可以
   
}

int main() 
{


    //隐式调用
    cout << Max(1, 2) << endl;
    cout << Max("狐狸1", "狐狸2") << endl;
    cout << Max(1.1, 2.3) << endl;
    //显示调用
    cout << Max<string>("狐狸23", "狐狸24") << endl;
    print<string, string>("1", "2");
    print<string, int>("1", 1234);
    //类中的成员函数是函数模板
    Fox fox;
    //隐式调用
    fox.printf(123);
    //显示调用
    fox.printf<string>("ILoveyou");
    //隐式调用
    fox.printfdata(12344);


    return 0;
}

类模板:被template修饰就是一个模板类

类模板不是一个实际类,所有用到类名的地方都需要类名<未知类型>方式使用

多文件中,类模板 中的声明和实现一定在一起的,不能分开写。

??

#include<iostream>
#include<string>
using namespace std;
template <class _Ty>
class Fox
{
public:
    Fox() {}
    Fox(string name) :name(name) {}
    void print();
protected:
    string name;
};
//在类外实现

template <class _Ty>
void Fox<_Ty>::print()
{
    cout << "类模板" << endl;
}
//包括继承中 也要写类名<未知类型>Fox
template<class _Ty>
class Foxson :public Fox<_Ty>
{
public:
    Foxson(string name) :Fox<_Ty>(name)//包括构造函数
    {

    }
protected:

};
//多个未知类型的模板类
template<class _Ty1, class _Ty2>
class Data
{
public:
    Data(_Ty1 one, _Ty2 two) :one(one), two(two) {}
    void print();
protected:
    _Ty1 one;
    _Ty2 two;
};
template<class _Ty2,class _Ty1>
void Data<_Ty2, _Ty1>::print()
{
    cout << one << endl;
    cout << two << endl;
}

int main() 
{
    //类模板必须显式调用
    Foxson<int> foxson("狐狸123");
    Data<string, int>data("狐狸1",3);
    data.print();
    foxson.print();
    return 0;
}

自定义类型当作模板参数

自定义类型也是模板,模板传入自定义,关键点在于重载运算符

#include<iostream>
#include<string>
using namespace std;
template <class _Ty>
class Fox
{
public:
    Fox() {}
    Fox(string name,int age) :name(name),age(age) {}
    void print();
    friend ostream& operator<<(ostream& out, const Fox& fox) //运算符重载
    {
        out << fox.name << " " << fox.age;
        return out;
    }
protected:
    string name;
    int age;
};
template <class _Ty>
void print(_Ty one)
{
    cout << one << endl;
}
int main() 
{
    print(53);

    Fox<string> fox("狐狸1",13);

    print(fox);
    return 0;
}
#include<iostream>
#include<string>
using namespace std;
class Fox
{
public:
	Fox(string name, int age) :name(name), age(age) {}
	friend ostream& operator<<(ostream& out, const Fox& fox)//需要运算符重载
	{
		out << fox.name << " " << fox.age;
		return out;
	}
protected:
	string name;
	int age;
};
template <class _Ty>
class Node
{
public:
	Node(_Ty data, Node<_Ty>* next) :data(data), next(next) {}
	_Ty getData()
	{
		return data;
	}
	Node<_Ty>* getNext()
	{
		return next;
	}
protected:
	_Ty data;
	Node<_Ty>* next;
};
template <class _Ty>
class List
{
public:
	List()
	{
		headNode = nullptr;
	}
	void insertList(_Ty data)
	{
		headNode = new Node<_Ty>(data, headNode);
	}
	void printList()
	{
		Node<_Ty>* pmove = headNode;
		while (pmove != nullptr)
		{
			cout << pmove->getData() << endl;
			pmove = pmove->getNext();
		}
		cout << endl;
	}
protected:
	Node<_Ty>* headNode;
};
int main() 
{
	List<Fox> list;
	list.insertList(Fox("狐狸1", 18));
	list.insertList(Fox("狐狸2", 13));
	list.insertList(Fox("狐狸3", 21));
	//将自定义类型当作数据存放进链表
	list.printList();
	//通过运算符重载输出数据
}

?模板嵌套:

#include <iostream>
using namespace std;
template <class _Ty1, class _Ty2>
class Fox
{
public:
	Fox(_Ty1 one, _Ty2 two) :one(one), two(two) {}
	friend ostream& operator<<(ostream& out, const Fox& fox)
	{
		out << fox.one << " " << fox.two;
		return out;
	}
protected:
	_Ty1 one;
	_Ty2 two;
};

template <class _Ty1, class _Ty2>
class Data
{
public:
	Data(_Ty1 one, _Ty2 two) :one(one), two(two) {}
	void print()
	{
		cout << one << " " << two << endl;
	}
protected:
	_Ty1 one;
	_Ty2 two;
};
template <class _Ty>
void print(_Ty data)
{
	cout << data << endl;
}
int main() 
{
	Data<Fox<string, int>, Fox<double, double>>
	mData2(Fox<string, int>("狐狸", 13), Fox<double, double>(100.0, 100.0));
	//上面一行顶下面4行
	Fox<string, int> fox1("狐狸",13);
	Fox<double, double>foxscore(100.0,100.0);
	Data<Fox<string, int>, Fox<double, double>> mData(fox1, foxscore);
	mData.print();
	//隐式调用
	print(Fox<string, int>("小狐狸", 15));
	//显式调用
	print<Fox<string, int>>(Fox<string, int>("小狐狸", 21));
	//起别名简化代码
	using FoxType= Fox<string, int>;
	print<FoxType>(FoxType("大狐狸", 3));


}

函数模板的重载

模板和普通函数,调用类型一致的情况下,优先调用普通函数

两个模板都成立,优先相似度高的模板

#include <iostream>
using namespace std;

void print(int a,string b) 
{
    cout << "普通函数" << endl;
}
template<class _Ty1,class _Ty2>
void print(_Ty1 a, _Ty2 b)
{
    cout << "两个类型" << endl;
}
template <class _Ty>
void print(_Ty a, _Ty b)
{
    cout << "一个类型" << endl;
}
int main() 
{
    print(15,string("dasdas"));//调用普通函数
    print<int, string>(12, "调用两个类型模板");//显示调用百分百调用模板
    print(12, string("调用两个类型模板"));

    print(12, 12); // 相似度高 调用一个类型
    return 0;



}

类模板特化

特化:局部特化 完全特化

#include<iostream>
#include<string>
using namespace std;
template<class _Ty1,class _Ty2 >
//普通类模板
//两个未知类型
class Fox
{
public:
    Fox(_Ty1 one, _Ty2 two) :one(one), two(two) {}
    void print() 
    {
        cout << one << "" << two << endl;
        cout << "原生模板" << endl;


    }
protected:
    _Ty1 one;
    _Ty2 two;

};
class Data
{
public:Data(int a, int b) :a(a), b(b) {};
      void printf()
      {
          cout << a << " " << b << endl;
  
      }

protected:
    int a;
    int b;

};
//特殊化 ,局部特化,一个未知参数
template<class _Ty >
class Fox<_Ty,_Ty>//产生特化类 类名要用:类型<类名>
{
public:
    Fox(_Ty one, _Ty two) :one(one), two(two) {}
    void print()
    {
        one.printf();
        two.printf();//针对特殊化数据做特殊化处理
        cout << "局部特化" << endl;
    }
protected:
    _Ty one;
    _Ty two;

};
//完全特化
template<>
class Fox<string, string>
{
public:
    Fox(string one, string two) :one(one), two(two) {};
    void print() 
    {
        cout << one << endl;
        cout << two << endl;
        cout << "完全特化" << endl;

    }
protected:
    string one;
    string two;
};

int main() 
{
    Fox<string,int> fox1("小狐狸",3);//原生模板
    fox1.print();
    Fox<string, string> fox2(string("大狐狸"), string("大大狐狸"));//完全特化
    fox2.print();
    Fox<Data, Data> dfox(Data(3, 4), Data(8, 9));//局部特化
    
    dfox.print();
}

针对不同的特化进行不同情况下模板的处理

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-13 12:37:21  更:2021-12-13 12:39:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:22:39-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码