当前位置: 首页 > article >正文

typename、非类型模板参数、模板参数的特化、模板类成员函数声明和定义分离、继承等的介绍

文章目录

  • 前言
  • 一、typename
  • 二、非类型模板参数
  • 三、模板参数的特化
    • 1. 函数模板参数的特化
    • 2. 类模板的特化
  • 四、模板类成员函数声明和定义分离
    • 1. 显示实例化(不建议使用)
    • 2. 将生命和定义写在同一个.h文件中
  • 五、 继承
  • 总结


前言

typename、非类型模板参数、模板参数的特化、模板类成员函数声明和定义分离、继承等的介绍


一、typename

void Print(vector<int>& v)
{
	vector<int>::iterator it = v.begin();
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}

	cout << endl;
}

对上述Print函数进行模板化,如果不加typename会出现如下情况:
在这里插入图片描述

#include <iostream>
#include <vector>
#include <list>
using namespace std;

template <class Container>
void Print(Container& v)
{
	typename Container::iterator it = v.begin(); // 此处要加typename修饰
	while (it != v.end())
	{
		cout << *it << " ";
		++it;
	}

	cout << endl;
}
int main()
{
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);

	Print(v);


	vector<double> v1;
	v1.push_back(1.1);
	v1.push_back(2.2);
	v1.push_back(3.3);
	v1.push_back(4.4);
	v1.push_back(5.5);

	Print(v1);


	list<double> lt;
	lt.push_back(1.14);
	lt.push_back(2.14);
	lt.push_back(3.14);
	lt.push_back(4.14);
	lt.push_back(5.14);

	Print(lt);

	return 0;
}

在这里插入图片描述

二、非类型模板参数

  • 比如一个静态栈,不仅需要接收类型参数, 还需要接收每个数组的长度
#include <iostream>
#include <vector>
#include <list>
using namespace std;

// 静态栈
template <class T, size_t N>
class Stack
{
public:
	Stack()
	{}
private:
	T _a[N];
	int _top;
};
int main()
{
	Stack<int, 10> st1; // 10
	Stack<double, 100> st2; // 100

	return 0;
}

在这里插入图片描述

三、模板参数的特化

特化指的就是 特殊化处理

1. 函数模板参数的特化

  • 函数模板个格式,虽然需要加template<>,但是大多数情况下,我们可以直接去掉,与原来的函数构成函数重载,达到特化的效果
#include <iostream>
using namespace std;
// 函数模板的特化
template <class T>
bool Less(T left, T right)
{
	return left < right;
}

// 函数模板的特化格式
template<>
bool Less<int*>(int* left, int* right)
{
	return *left < *right;
}

int main()
{
	cout << Less(1, 2) << endl;
	int a = 2, b = 1;
	cout << Less(&a, &b) << endl;

	return 0;
}

在这里插入图片描述

2. 类模板的特化

类模板的特化包括 全特化,偏特化(半特化), 限制类型为指针, 限制类型为引用

#include <iostream>
using namespace std;

// 类模板特化

template <class T1, class T2>
class A
{
public:
	A() { cout << "A<T1, T2>" << endl; }
private:
};

// 全特化
template<>
class A<int, double>
{
public:
	A() { cout << "A<int, double>" << endl; }
private:
};


// 偏特化
template <class T1>
class A<T1, double>
{
public:
	A() { cout << "A<T1, double>" << endl; }
private:
};

// 对类型进行限制---指针
template <class T1, class T2>
class A<T1*, T2*>
{
public:
	A() { cout << "A<T1*, T2*>" << endl; }
private:
};

// 对类型限制---引用
template <class T1, class T2>
class A<T1&, T2&>
{
public:
	A() { cout << "A<T1&, T2&>" << endl; }
private:
};


int main()
{
	A<int, int> a1;
	A<int, double> a2;
	A<double, double> a3;
	A<char, double> a4;
	A<int*, double> a5;
	A<int*, double*> a6;
	A<void*, void*> a7;
	A<int&, double&> a8;

	return 0;
}

在这里插入图片描述

四、模板类成员函数声明和定义分离

模板类成员函数声明和定义分离 有两种方式:
一种是: 在函数的定义处显示实例化
另一种是: 将生命和定义写在同一个.h文件中,(有些还将这种文件以.hpp作为后缀)

模板类成员函数声明和定义直接分离,因为模板类型T没有进行实例化,编译器在链接阶段无法找到正确的地址,所以会出现编译报错。

1. 显示实例化(不建议使用)

// Stack.h
#pragma once
#include <vector>

namespace hhb
{
	template<class T, class Container = std::vector<T>>
	class stack
	{
	public:
		void push(const T& x);

		void pop();

		bool empty()
		{
			return _con.empty();
		}

		const T& top()
		{
			return _con.front();
		}

		
	private:
		Container _con;
	};
	
}


// Stack.cpp
#include "Stack.h"

namespace hhb
{
	template<class T, class Container>
	void stack<T, Container>::push(const T& x)
	{
		_con.push_back(x);
	}

	template <class T, class Container>
	void stack<T, Container>::pop()
	{
		_con.pop_back();
	}

	template
	class stack<int>;

	template
	class stack<double>;
}

// test.cpp
#include "Stack.h"

int main()
{
	hhb::stack<int> st;

	st.push(1);
	st.pop();


	hhb::stack<double> st1;

	st1.push(1.1);
	st1.pop();

	return 0;
}
  • 不会有编译错误

2. 将生命和定义写在同一个.h文件中

// Stack.h
#pragma once
#include <vector>

namespace hhb
{
	template<class T, class Container = std::vector<T>>
	class stack
	{
	public:
		void push(const T& x);

		void pop();

		bool empty()
		{
			return _con.empty();
		}

		const T& top()
		{
			return _con.front();
		}

		
	private:
		Container _con;
	};



	template<class T, class Container>
	void stack<T, Container>::push(const T& x)
	{
		_con.push_back(x);
	}

	template <class T, class Container>
	void stack<T, Container>::pop()
	{
		_con.pop_back();
	}
	
}

// test.cpp
#include "Stack.h"

int main()
{
	hhb::stack<int> st;

	st.push(1);
	st.pop();


	hhb::stack<double> st1;

	st1.push(1.1);
	st1.pop();

	return 0;
}
  • 不会有编译错误

五、 继承

访问限定符的权限 : public > protected > privated;
继承是有基类以继承方式继承给派生类
继承方式: 有三种 以 public 、 protected、 private 三种方式进行继承。
派生类对基类成员变量/成员函数的访问方式取决于: 基类的成员变量和成员函数的访问限定符以及派生类的继承方式:

  1. 基类的成员若为private, 则在派生类中无法看见(访问)基类private的成员
  2. 基类的protected和public成员, 与派生类的继承方式权限进行比较,权限小的即为在派生类中访问基类成员的访问方式。
#include <iostream>
using namespace std;
class Person
{
public:
	Person()
	{}
	void print()
	{
		cout << "_name: " << _name <<  endl;
		cout << "_age: " << _age << endl;
	}
protected:
	string _name = "perter";
	int _age = 10;
};


class student : public Person
{
public:
private:
	int _sid;
};

class teacher : public Person
{
public:
private:
	int _tid;
};

int main()
{
	student s;
	s.print();

	teacher t;
	t.print();


	return 0;
}

在这里插入图片描述

总结

typename、非类型模板参数、模板参数的特化、模板类成员函数声明和定义分离、继承等的介绍


http://www.kler.cn/news/318483.html

相关文章:

  • 滚雪球学SpringCloud[6.3讲]: 分布式日志管理与分析
  • 常见统计量与其抽样分布
  • python异步处理
  • [SDX35+WCN6856]SDX35 + WCN6856 WiFi 起来之后,使用终端连接会导致系统重启
  • dotnet4.0编译问题
  • 【系统架构设计师】专题:系统质量属性和架构评估
  • 康养为松,智能为鹤:华为全屋智能画出的松鹤长春图
  • 2024.9.24 数据分析
  • 努比亚z17努比亚NX563j原厂固件卡刷包下载_刷机ROM固件包下载-原厂ROM固件-安卓刷机固件网
  • 智慧城市主要运营模式分析
  • [附源码]宠物领养管理系统+SpringBoot
  • css实现居中的方法
  • C++ prime plus-4-编程练习
  • vue echarts tooltip使用动态模板
  • Web3技术在元宇宙中的应用:从区块链到智能合约
  • 搜维尔科技:手指舞测试Manus VR数据手套手指追踪功能
  • HtmlCss 基础总结(基础好了才是最能打的)五
  • 代码随想录算法训练营第二十八天| 122.买卖股票的最佳时机 II、55. 跳跃游戏、45.跳跃游戏 II、1005.K次取反后最大化的数组和
  • 线程知识点补充
  • uniapp map设置高度为100%后,会拉伸父容器的高度
  • 练习题 - Django 4.x Models Meta 元数据选项
  • C++类和对象(中)【下篇】
  • 考研数据结构——C语言实现插入排序
  • 2024百度的组织架构和产品分布
  • Java Collectors工具类
  • js进阶——词法作用域
  • 无人机蜂群作战会成为未来战争的主要形式吗,该如何反制呢?
  • 前端——阿里图标的使用
  • Qt窗口——对话框
  • EventSource 和 WebSocket的区别