注:本文仅作个人做笔记复习用,不具有教学意义!
目录
Traits2:如果一个类模板中,全部的成员都是公有数据类型,这个模板就是一个独立的数据类型表,用来规范数据
- #include
-
- using namespace std;
-
- //函数模板
- template<typename T>
- void myswap(T &a,T &b) {
- T temp;
- temp = a;
- a = b;
- b = temp;
- }
-
- int main() {
-
- int a = 1, b = 2;
- //模板函数,编译器根据传入参数生成的模板特例
- myswap(a, b);
- cout << a << " " << b << endl;
-
- double c = 2.2, d = 3.3;
- //模板函数,编译器根据传入参数生成的模板特例
- myswap(c, d);
- cout << c << " " << d << endl;
-
- return 0;
- }
- template<typename T>
- void fun(T& a,T& b) {
- cout << "template被调用" << endl;
- }
-
- void fun(char c,int y) {
- cout << "普通函数被调用" << endl;
- }
-
- int main() {
- char ch = 'a';
- int data = 23;
- fun<int>(ch, data);//❌,函数模板不提供隐式类型转化,必须严格遵守T的类型定义
- fun(ch, data);//✔,调用普通函数
- return 0;
- }
- template<typename T>
- void fun(T& a,T& b) {
- cout << "template被调用" << endl;
- }
-
- void fun(int &a,int &b) {
- cout << "普通函数被调用" << endl;
- }
-
- int main() {
- int data1 = 32;
- int data2 = 23;
- fun<int>(data1, data2);//template被调用
- fun(data1, data2);//普通函数被调用
- return 0;
- }
编译器在处理函数模板的时候能够生成任意类型的函数
根据调用的实际产生不同的函数:
编译器会对函数模板进行二次编译:这是参数化的基础,也是成为编译时多态的由来。
在声明的地方对模板代码本身进行编译,在调用的地方对参数化以后的具体调用进行编译
【C++】模板声明与定义不分离_Yngz_Miao的博客-CSDN博客_c++模板声明
- #include
- using namespace std;
-
- template<class T1,class T2>
- class MyClass {
- public:
- T1 _t1;
- T2 _t2;
- MyClass(T1 t1, T2 t2) :_t1(t1), _t2(t2) {}
- void print() {
- cout << _t1 << "," << _t2 << endl;
- }
- };
-
- int main() {
-
- MyClass<int, int>mc(1, 2);
- mc.print();
-
- return 0;
- }
MyArray.hpp:
- #pragma once
-
- template<class T,int n>
- class MyArray {
- public:
- MyArray();
- MyArray(int length);
- ~MyArray();
-
- int size();
- T get(int num);
- T& operator[](int num);
- void set(T data, int num);
- public:
- T* pt;
-
- };
-
- template<class T, int n>
- inline MyArray
::MyArray() - {
- this->pt = new T[n];
- }
-
- template<class T, int n>
- inline MyArray
::MyArray(int length) - {
- this->pt = new T[length];
- }
-
- template<class T, int n>
- inline MyArray
::~MyArray() - {
- delete[]this->pt;
- }
-
- template<class T, int n>
- inline int MyArray
::size() - {
- return n;
- }
-
- template<class T, int n>
- inline T MyArray
::get(int num) - {
- if (num >= n || num < 0) {
- //exception;
- }
- else {
- return *(this->pt + num);
- }
- }
-
- template<class T, int n>
- inline T& MyArray
::operator[](int num) - {
- if (num >= n || num < 0) {
-
- }
- else {
- return *(pt + num);
- }
- }
-
- template<class T, int n>
- inline void MyArray
::set(T data, int num) - {
- if (num >= n || num < 0) {
- //
- }
- else {
- *(pt + num) = data;
- }
- }
-
-
-
-
-
-
-
MyArray.cpp
- #include
- #include "MyArray.hpp"
- using namespace std;
-
- int main() {
- MyArray<int, 5>arr;
- for (int i = 0; i < arr.size(); i++) {
- arr.set(i * 10, i);
- cout << arr[i] << endl;
- }
- return 0;
- }

模板类继承模板类:
- #include
- #include
- using namespace std;
-
- template<class T>
- class MyClass {
- public:
- T x;
- MyClass(T t) :x(t) {}
- virtual void print() = 0;
- };
-
- template<class T>
- class NewClass :public MyClass
{ - public:
- T y;
- NewClass(T t1, T t2) :MyClass(t1), y(t2) {}
- void print() {
- cout << "x=" << x << " y=" << y << endl;
- }
- };
-
- int main() {
- MyClass<int>* p = new NewClass<int>(10, 8);
- p->print();
- return 0;
- }
模板类继承普通类:
- class XYZ {
- public:
- int x, y, z;
- XYZ(int a, int b, int c) :x(a), y(b), z(c) {}
- virtual void print() {
- cout << x << " " << y << " " << z << " " << endl;
- }
- };
-
- template<class T>
- class GoodsXYZ :public XYZ {
- public:
- int t;
- GoodsXYZ(int t1, int a, int b, int c) :XYZ(a, b, c), t(t1) {}
- void print() {
- cout << "T 类型的值" << t << endl;
- cout << x << " " << y << " " << z << endl;
- }
- };
普通类继承模板类
- class RunClass :public GoodsXYZ<int> {
- public:
- int dd = 1000;
- RunClass(int a2, int b2, int c2, int d2) :GoodsXYZ<int>(a2, b2, c2, d2) {}
- void print() {
- cout << dd << x << y << z;
- }
- };
- #include
- using namespace std;
-
- template<class T>
- class MyTestNestClass {
- public:
- class nClass {
- public:
- int num;
- };
- nClass nObj1, nObj2;
-
- template<class V>
- class RunClass {
- public:
- V v1;
- };//嵌套类模板,不能直接初始化
- RunClass
t1; - RunClass<double>t2;
- };
-
- int main() {
- MyTestNestClass<int>myObj1;
- myObj1.nObj1.num = 10;
- myObj1.t1.v1 = 13;
- myObj1.t2.v1 = 6.18;
- cout << myObj1.nObj1.num<< endl;
- cout << myObj1.t1.v1 << endl;
- cout << myObj1.t2.v1 << endl;
- return 0;
- }
左值与右值:
- int a = 10;
- int b = 20;
- int c = a + b;
-
- __asm {
- mov eax,a
- mov ebx,b
- add eax,ebx
- mov c,eax
- }
左值:
右值:
右值引用:使得右值变成一个与左值完全相同的持久对象
- int x = 10, y = 20;
- int&& right = x + y;
如果有一个临时对象,那么使用浅拷贝会有巨大的意义
当我们需要具有”转移语意“的拷贝构造函数时,浅拷贝的意义就凸显了。
- #include
- using namespace std;
-
- class Foo {
- public:
- Foo(int x) {
-
- }
-
- Foo(const Foo& r) {
- //this->p = r.p;//浅拷贝,p和r.p指向了同一个地址
- p = new int;
- *p = *(r.p);//深拷贝
- }
-
- Foo(Foo&& r) {
- cout << "Foo(Foo&&)" << endl;
- p = r.p;//p和r.p指向了同一个地址
- r.p = nullptr;//源对象r放弃资源所有权
- }
-
- private:
- int* p;
- };
-
- Foo func() {
- Foo foo(100);
- return foo;
- }
-
- int main() {
- Foo f(func());//资源所有权发生转移,资源位置没有改变而所属对象变化
-
- return 0;
- }

- #include
- using namespace std;
-
- void Func(int& x) {
- cout << "左值引用" << endl;
- }
-
- void Func(int&& x) {
- cout << "右值引用" << endl;
- }
-
- void Func(const int& x) {
- cout << "左值常引用" << endl;
- }
-
- void Func(const int&& x) {
- cout << "右值常引用" << endl;
- }
-
- template<typename T>
- void FuncT(T&& a) {
- Func(std::forward
(a));//使用std::forward进行类型推导 - }
-
- int main() {
- FuncT(10);
-
- int a;
- FuncT(a);
-
- FuncT(std::move(a));
-
- const int b = 10;
- FuncT(b);
-
- FuncT(std::move(b));
-
- return 0;
- }
实现内嵌数据类型->从模板传入类型
- template<typename T>
- struct map {
- typedef T value_type;
- typedef T& reference;
- typedef T* pointer;
- };
-
- template<typename T,typename U>
- class A :public TypeTb1
{ -
- };
-
- int main() {
-
- map<int>::value_type a = 100;
- map<int>::reference b = a;
- map<int>::pointer c = &a;
-
- return 0;
- }
①定义一个规范类模板类型的基类模板
②凡是继承了这个类型表的模板,它的访问类型就被确定
STL库中,设计人员经常使用这种技巧:
- template<class _A1m,class _A2, class R>
- class binary
- {
- typedef _A1 Arg1;//第一个形参类型
- typedef _A2 Arg2;//第二个形参类型
- typedef R Rtn;//返回值类型
- };
举例:
- template<typename TR,typename T1,typename T2>
- class Add :public binary
{- public:
- TR bFunction(const T1& x, const T2& y)const {
- return x + y;
- }
- };
-
- int main() {
-
- double a = 100.01, b = 20.2;
- Add<double, double, double>addObj;
- cout << addObj.bFunction(a, b) << endl;
-
-
- return 0;
- }
因为Add包含了binary的类型数据表,因此系统中的其他模块就可以使用Add::Arg1,Add::Arg2,Add::Rtn这种方式和Add本身进行对接。
这种数据类型的抽象,达到了多个系统模块之间的类型统一。
Traits3:非侵入式STL类型设计与数据类型
- #include
- using namespace std;
-
- class Test1;
- class Test2;
- //两个类模板规范一个统一的接口
- template <typename T>
- class TypeTb1 {
-
- };
-
- //特化模板1
- template<>
- class TypeTb1
{ - public:
- typedef char ret_type;
- typedef int par1_type;
- typedef double par2_type;
- };
-
- //特化模板2
- template<>
- class TypeTb1
{ - public:
- typedef double ret_type;
- typedef double par1_type;
- typedef int par2_type;
- };
-
- template<typename T>
- class Test {
- public:
- typename TypeTb1
::ret_type compute - (
- typename TypeTb1
::par1_type x, - typename TypeTb1
::par2_type y - )
- {
- return x;
- }
- };
-
- int main() {
- Test
t1; - cout << t1.compute(65, 6.18) << endl;
- return 0;
- }
Traits4:Traits的原理及应用:Iterator
- template<typename T>
- struct Traits{
-
- };
-
- template<typename T>
- struct Traits
{ - typedef T value_type;
- typedef value_type* pointer;
- typedef value_type& reference;
- };
-
- int main() {
- Traits<double*>::value_type t2 = 4.44;
- cout << t2 << endl;
- return 0;
- }
shared_ptr的仿真实现Shared_ptr:
- #include
- using namespace std;
-
- template<typename T>
- class Shared_ptr;
-
- template<typename T>
- class Res_ptr {
- private:
- T* res_p;
- int use_num;
- Res_ptr(T* p) :res_p(p), use_num(1) {
- cout << "res 构造函数" << endl;
- }
- ~Res_ptr() {
- cout << "res 析构函数" << endl;
- }
- friend class Shared_ptr
; - };
-
- template<typename T>
- class Shared_ptr {
- public:
- Shared_ptr(T* p) :ptr(new Res_ptr
(p)) { - cout << "Shared_ptr的构造函数 " << " use_num=" << ptr->use_num << endl;
- }
-
- Shared_ptr(const Shared_ptr& origin) :ptr(origin.ptr) {
- ++ptr->use_num;
- cout << "Shared_ptr的拷贝构造函数" << " use_num=" << ptr->use_num << endl;
- }
-
- ~Shared_ptr() {
- cout<<"Shared_ptr的析构函数"<< " use_num=" << ptr->use_num << endl;
- if (--ptr->use_num == 0) {
- delete ptr;
- }
- }
-
- private:
- Res_ptr
* ptr;//指向计数类Res_ptr - };
-
- int main() {
-
- {
- Shared_ptr<int>hpA = Shared_ptr<int>(new int(42));
- {
- Shared_ptr<int>hpB(hpA);
- Shared_ptr<int>hpC(hpB);
- Shared_ptr<int>hpD = hpA;
- }
- cout << "内层括号结束!" << endl;
- }
- cout << "中层括号结束!" << endl;
- return 0;
- }

-
相关阅读:
001 Creating your first app with PySide6
轻游戏风格虚拟资源付费下载模板Discuz论坛模板
HTML做一个简单的页面(纯html代码)地球专题学习网站
AI内容生成时代:该如何和AI对话?
选择器汇总
SpringSecurity自定义多Provider时提示No AuthenticationProvider found for问题的解决方案与原理(四)
FlyBird
【学习笔记】CF1784F Minimums or Medians
动态代理解决方案
端到端图像压缩《Checkerboard Context Model for Efficient Learned Image Compression》
-
原文地址:https://blog.csdn.net/Jason6620/article/details/126223543