12.C++模板

  1. 函数模板

    1. 什么是模板 : 把类型当做未知量,可以忽略类型影响

    2. 声明模板的语法

      //单个未知类型
      template <typename _type>	   //_type 随便改 ,就是类型代号
      _type Max(_type a, _type b)
      {
      	return a > b ? a : b;
      }
      //可以多个未知类型
      template <typename _type1,typename _type2 >
      void print(_type1 one,_type2 two)
      {
      	cout<<one<<endl;
          cout<<two<<endl;
      }
      //typename 可以换成class
      template  <class _type>
      void print(_type a)
      {
      	cout<<a<<endl;    
      }

    3. 调用函数模板

      • 隐式调用 : 正常的函数传参即可调用

      • 显示调用: 函数名<类型名>(参数)

    4. 函数模板的两种形态

      • 普通函数当做函数模板

      • 类的成员函数是函数模板

    5. 函数模板特殊的写法

      • 缺省写法

      • 存在常量类型

    6. #include <iostream>
      using namespace std;
      
      //typename 可以换成class
      template<typename _type>
      _type Max(_type a,_type b) {
      	return a>b?a:b;
      }
      
      template<typename _type1,typename _type2>
      void print(_type1 a,_type2 b) {
      	cout << a << endl;
      	cout << b << endl;
      }
      
      template<class _type3,size_t size>//size可以缺省
      void printArray(_type3 array) {
      	for (int i=0;i<size;i++)
      	{
      		cout<<array[i]<<" ";
      	}
      	cout << endl;
      }
      //类的成员函数是函数模板
      class student
      {
      public:
      	template<class _type1,class _type2>
      	void print(_type1 one,_type2 two) {
      		cout << one << " " << two << endl;
      	}
      	template<class _type3, class _type4>
      	void print1(_type3 one, _type4 two);
      protected:
      private:
      };
      //在类外实现不能省略template这一块
      template<class _type3,class _type4>
      void student::print1(_type3 one, _type4 two) {
      	cout << one << " " << two << endl;
      }
      
      int main() {
      	//隐式调用
      	cout<<Max(1.4, 1.5)<<endl;
      	print("Hello", 12);
      	print("Hello", "World");
      	//显式调用
      	cout<<Max<string>("ABC", "abc")<<endl;
      	print<int, string>(5, "abc");
      	print<string, string>("asd", "QWE");
      
      	int array[5] = { 1,3,5,7,8 };
      	printArray<int*, 5>(array);
      	//类的成员函数是函数模板
      	student stu;
      	stu.print("张三","男");
      	stu.print1(22, 95);
      
      	return 0;
      }

  2. 类模板

    1. 生成一个类模板

      template<class _type>
      class ClassName
      {
      	public:
          protected:
      }
      //只要被template修饰就是一个模板类,用没用未知类型没关系 
    2. 类模板调用

      • 必须采用显式调用

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

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

    4. #include<iostream>
      #include <string>
      using namespace std;
      template<class _type1,class _type2>
      class Parent
      {
      public:
      	Parent() = default;
      	Parent(_type1 one, _type2 two) :one(one), two(two) {}
      	void print();
      protected:
      	_type1 one;
      	_type2 two;
      private:
      };
      template<class _type1,class _type2>
      void Parent<_type1,_type2>::print() {
      	cout << one << " " << two << endl;
      }
      template<class _type1,class _type2>
      class Son :public Parent<_type1,_type2> {
      public:
      	//类模板不是一个实际类型,所以所有用到类名的地方都需要使用 : 类名<未知类型> 方式使用
      	Son(_type1 fone, _type2 ftwo, _type1 one, _type2 two):Parent<_type1,_type2>(fone,ftwo),one(one),two(two){}
      	void print() {
      		cout <<"基类:" << Parent<_type1,_type2>::one << " " << Parent<_type1,_type2>::two << endl;
      		cout <<"子类:" << one << " " << two << endl;
      	}
      protected:
      	_type1 one;
      	_type2 two;
      private:
      };
      
      
      int main() {
      	//必须采用显式调用
      	Parent<string,int> father;
      	Son<string, int> son("张三", 35, "张四", 10);
      	son.Parent<string,int>::print();
      	son.print();
      	return 0;
      }

  3. 自定义类型当做模板参数

    1. 基本自定义类型

    2. 自定义类型也是一个模板

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

    4. #include<iostream>
      #include <string>
      using namespace std;
      
      class student
      {
      public:
      	student(string name="", int age=0) :name(name), age(age) {}
      	friend ostream& operator<<(ostream& out, const student& object) {
      		out << object.name << " " << object.age;
      		return out;
      	}
      	bool operator>(student& stu) {
      		return this->age > stu.age;
      	}
      protected:
      	string name;
      	int age;
      private:
      };
      
      template<class _type>
      void print(_type object) {
      	cout << object << endl;
      }
      template<class _type1>
      _type1 Max(_type1 a,_type1 b) {
      	return a > b ? a : b;
      }
      
      template<class _type>
      class Node
      {
      public:
      	Node(_type data,Node<_type>*next):data(data),next(next){}
      	_type getData() {
      		return data;
      	}
      	Node<_type>* getNext() {
      		return next;
      	}
      protected:
      	_type data;
      	Node<_type>* next;
      private:
      };
      
      template<class _type>
      class List {
      public:
      	List() {
      		headNode = nullptr;
      	}
      	void insertList(_type data) {
      		headNode = new Node<_type>(data, headNode);
      	}
      	void print() {
      		Node<_type>* pMove = headNode;
      		while (pMove!=nullptr)
      		{
      			cout << pMove->getData() << endl;
      			pMove = pMove->getNext();
      		}
      	}
      protected:
      	Node<_type>* headNode;
      private:
      
      };
      
      
      int main() {
      	//print(student("张三",20));
      	//student stu1("李四", 23);
      	//student stu2("王五", 25);
      	//cout << Max(stu1, stu2) << endl;
      
      	//链表插入普通类型
      	List<int> datalist;
      	datalist.insertList(1);
      	datalist.insertList(2);
      	datalist.insertList(3);
      	datalist.insertList(4);
      	datalist.insertList(5);
      	datalist.print();
      
      	//链表插入自定义类型
      	List<student> list;
      	list.insertList(student("张三", 20));
      	list.insertList(student("李四", 18));
      	list.insertList(student("王五", 22));
      	list.insertList(student("周六", 35));
      	list.print();
      
      
      	return 0;
      }

  4. 嵌套模板

    #include<iostream>
    #include <string>
    using namespace std;
    template<class _type1,class _type2>
    class student
    {
    public:
    	student(_type1 one,_type2 two):one(one),two(two){}
    	void print() {
    		cout << one << " " << two << endl;
    	}
    protected:
    	_type1 one;
    	_type2 two;
    private:
    };
    
    template<class _type1,class _type2>
    class Data
    {
    public:
    	Data(_type1 one, _type2 two) :one(one), two(two) {}
    	friend ostream& operator<<(ostream& out, const Data& object) {
    		return out << object.one << " " << object.two << " ";
    	}
    protected:
    	_type1 one;
    	_type2 two;
    private:
    };
    
    int main() {
    	Data<string, int>stuInfo("张三", 22);
    	Data<string, double>stuScore("男", 88);
    	student<Data<string, int>, Data<string, double>>stu(stuInfo, stuScore);
    	stu.print();
    
    	student<Data<string, int>, Data<string, int>>stu1(Data<string, int>("李四", 25), Data<string, int>("男", 87));
    	stu1.print();
    
    	return 0;
    }

  5. 函数模板重载

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

    2. 两个模板同时成立,优先调用类型相似度搞的那个

    3. #include<iostream>
      #include <string>
      using namespace std;
      
      void print(int a, string b) {
      	cout << "普通函数" << endl;
      }
      template<class _type>
      void print(_type a,_type b) {
      	cout << "一个类型" << endl;
      }
      template<class _type1,class _type2>
      void print(_type1 a,_type2 b) {
      	cout << "两个类型" << endl;
      }
      
      int main() {
      	print(1, string("hello"));
      	print(1, "hello");//优先调用"两个类型","  "默认为char*类型
      	print(1, 2);
      	print("world", 2);
      
      
      
      	return 0;
      }

  6. 类模板特化

    1. 局部特化

    2. 完全特化

    3. #include<iostream>
      #include <string>
      using namespace std;
      template<class _type1,class _type2>
      class Student
      {
      public:
      	Student(_type1 one,_type2 two):one(one),two(two){}
      	void print() {
      		cout << "普通函数" << endl;
      		cout << one << " " << two << endl;
      	}
      protected:
      	_type1 one;
      	_type2 two;
      private:
      };
      
      //局部特化,特殊化
      template<class _type>
      class Student<_type,_type> {
      public:
      	Student(_type one, _type two):one(one),two(two){}
      	void print() {
      		cout << "局部特化" << endl;
      		cout << one << " " << two << endl;
      	}
      protected:
      	_type one;
      	_type two;
      private:
      };
      
      //完全特化
      template<>
      class Student<string, int> {
      public:
      	Student(string name, int age):name(name),age(age){}
      	void print() {
      		cout << "完全特化" << endl;
      		cout << name << " " << age << endl;
      	}
      protected:
      	string name;
      	int age;
      private:
      };
      
      int main() {
      	//原生模板
      	Student<int, string>Stu(1001, "李四");
      	Stu.print();
      
      	//局部特化模板
      	Student<string, string>stu("张三", "男");
      	stu.print();
      
      	Student<int, int>stu1(88, 89);
      	stu1.print();
      
      	//完全特化
      	Student<string, int>stu2("张三", 18);
      	stu2.print();
      
      
      	return 0;
      }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值