👂 总有一天你会出现在我身边 - 棱镜乐队 - 单曲 - 网易云音乐
👂 カタオモイ(单相思) - Aimer - 单曲 - 网易云音乐
目录
🌳函数模板基本语法
#include<iostream>
using namespace std;
//函数模板, 将类型参数化
//一个函数实现各种数据类型
//函数模板
template<typename T> //声明一个模板 T表示通用数据类型 不报错
void mySwap(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
void test01()
{
int a = 10, b = 20;
//利用函数模板交换
//1,自动类型推导
mySwap(a, b); //根据传入的类型, 自动推导
cout<<"a = "<<a<<endl<<"b = "<<b<<endl;
//2,显示指定类型
mySwap<int>(a, b); //指定上面<>中的T的类型
cout<<"a = "<<a<<endl<<"b = "<<b<<endl;
}
int main()
{
test01();
system("pause");
return 0;
}
//1, 函数模板 关键字 template
//2, 两种方式:自动类型推导 和 显示指定类型
//3, 提高复用性 类型参数化
🌳函数模板注意事项
#include<iostream>
using namespace std;
//函数模板注意事项
//1,自动类型推导,必须推导出一致的数据类型 T
template<typename T> //typename 等价于 class
void mySwap(T &a, T&b)
{
T temp = a;
a = b;
b = temp;
}
void test01()
{
int a = 10, b = 20;
char c = 'c';
//mySwap(a, b); //正确!
//mySwap(a, c); //错误! 推导不出一致的 T 类型
cout<<"a = "<<a<<" b = "<<b<<endl;
}
//2,模板必须确定出 T 的数据类型
template<class T>
void func()
{
cout<<"func 调用"<<endl;
}
void test02()
{
//func(); //错误!error: no match function to ...
func<int>(); //正确!
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
🌳函数模板案例 -- 数组排序
#include<iostream>
using namespace std;
//实现通用 对数组排序的函数
//大到小
//选择排序
//测试 char 和 int
//交换函数模板
template<class T>
void mySwap(T &a, T &b)
{
T temp = a;
a = b;
b = temp;
}
//排序算法模板
template<class T>
void mySort(T arr[], int len) //传入数组, 数组名即地址, 不需要引用传递
{
for(int i = 0; i < len; ++i) {
int Max = i; //假设第一个数最大值
for(int j = i + 1; j < len; ++j) {
if(arr[Max] < arr[j]) { //交换
Max = j; //更新最大值下标
}
}
if(Max != i) {
//交换Max 和 i 下标元素的值
mySwap(arr[Max], arr[i]);
}
}
}
//打印数组模板
template<class T>
void printArray(T arr[], int len)
{
for(int i = 0; i < len; ++i)
cout<<arr[i]<<" ";
cout<<endl;
}
void test01()
{
//测试char数组
char charArr[] = "badcfe";
int num = sizeof(charArr) / sizeof(char);
mySort(charArr, num);
printArray(charArr, num);
}
void test02()
{
//测试int数组
int intArr[] = {1,8,5,2,11,8,8};
int num = sizeof(intArr) / sizeof(int);
mySort(intArr, num);
printArray(intArr, num);
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
🌳普通函数与函数模板区别
#include<iostream>
using namespace std;
//普通函数与函数模板区别
//1,普通函数调用时 可以隐式类型转换
//2,函数模板 自动类型推导 不能隐式类型转换
//3,函数模板 显示指定类型 可以隐式转换
//普通函数
int myAdd01(int a, int b)
{
return a + b;
}
//函数模板
template<class T>
T myAdd02(T a, T b)
{
return a + b;
}
void test01()
{
int a = 10, b = 20;
char c = 'c';
//cout<<myAdd01(a, b)<<endl;
//'c'隐式转换成整形
cout<<myAdd01(a, c)<<endl; //c - 99, 10 + 99 == 109
//自动类型推导
//cout<<myAdd02(a, b)<<endl; //error, 不能隐式转换, char与int
//显示指定类型
cout<<myAdd02<int>(a, c)<<endl;
}
int main()
{
test01();
system("pause");
return 0;
}
🌳普通函数与模板函数调用规则
如果提供了函数模板,就不要写普通函数了,否则容易出现 二义性
#include<iostream>
using namespace std;
//普通函数与函数模板调用规则
//1,如果函数模板和普通函数都可以调用,优先调用普通函数
//2,空模板参数列表 来强制调用 函数模板
//3,函数模板可函数重载
//4,如果函数模板可产生更好匹配,优先函数模板
void myPrint(int a, int b)
{
cout<<"调用 普通函数"<<endl;
}
template<class T>
void myPrint(T a, T b)
{
cout<<"调用 模板"<<endl;
}
template<class T>
void myPrint(T a, T b, T c)
{
cout<<"调用 重载 模板"<<endl;
}
void test01()
{
//1,
int a = 10, b = 20;
myPrint(a, b);
//2,空模板参数列表 强制调用函数模板
myPrint<>(a, b);
//3,
myPrint(a, b, 100);
//4,如果函数模板产生更好的匹配 优先函数模板
char c1 = 'a', c2 = 'b';
myPrint(c1, c2);
}
int main()
{
test01();
system("pause");
return 0;
}
🌼模板的局限性
1,具体化的模板,解决自定义类型的通用化
2,模板,是为了STL能运用系统提供的模板
#include<iostream>
#include<string>
using namespace std;
//模板局限性 非万能
//特定数据类型 需要具体化实现
class Person
{
public:
Person(string name, int age)
{
this->m_Age = age;
this->m_Name = name;
}
string m_Name;
int m_Age;
};
//对比两个数据是否相等
template<class T>
bool myCompare(T &a, T &b)
{
if(a == b)
return true;
else
return false;
}
//利用具体化Person的版本 具体化优先调用
template<> bool myCompare(Person &p1, Person &p2)
{
if(p1.m_Name == p2.m_Name && p1.m_Age == p2.m_Age)
return true;
else
return false;
}
void test01()
{
int a = 10, b = 20;
bool ret = myCompare(a, b);
if(ret)
cout<<"a == b"<<endl;
else
cout<<"a != b"<<endl;
}
void test02()
{
Person p1("Tom", 10);
Person p2("Tom", 10);
bool ret = myCompare(p1, p2);
if(ret)
cout<<"a == b"<<endl;
else
cout<<"a != b"<<endl;
}
int main()
{
test01();
test02();
system("pause");
return 0;
}
🌼类模板基本语法
类模板与函数模板语法几乎一样
区别是,类模板声明模板template下一行加类,函数模板声明模板template下一行加函数
#include<iostream>
#include<string>
using namespace std;
//类模板
template<class NameType, class AgeType>
class Person
{
public:
Person(NameType name, AgeType age)
{
this->m_Name = name;
this->m_Age = age;
}
void showPerson()
{
cout<<"name: "<<this->m_Name<<" age: "<<this->m_Age<<endl;
}
NameType m_Name;
AgeType m_Age;
};
void test01()
{
//类型参数化
//1, 将string, int传到NameType, AgeType
//2, 将"孙悟空", 999 传到name, age
Person<string, int> p1("孙悟空", 999);
p1.showPerson();
}
int main()
{
test01();
system("pause");
return 0;
}
🌼类模板与函数模板区别
1,类模板只能用显式指定类型的方式
2,类模板的模板参数列表可以有默认参数
#include<iostream>
#include<string>
using namespace std;
//类模板与函数模板区别
template<class NameType, class AgeType = int> //<>里的是模板参数列表
class Person
{
public:
Person(NameType name, AgeType age)
{
this->m_Name = name;
this->m_Age = age;
}
void showPerson()
{
cout<<"name: "<<m_Name<<" age: "<<m_Age<<endl;
}
NameType m_Name;
AgeType m_Age;
};
//1, 类模板没有自动类型推导的使用方式
void test01()
{
//Person p("孙悟空", 110); //× p之前缺少模板参数
Person<string, int>p("孙悟饭", 999); //√ 只能用显示指定类型
p.showPerson();
}
//2,类模板在模板的参数列表中可以有默认参数
void test02()
{
Person<string>p("猪八戒",1234); //上面类模板声明时, 有默认参数int
p.showPerson();
}
int main()
{
test01();
cout<<endl;
test02();
system("pause");
return 0;
}
🌼类模板中成员函数创建时机
#include<iostream>
using namespace std;
//类模板中成员函数的创建时机
//类模板中成员函数 调用时才创建
class Person1
{
public:
void showPerson1()
{
cout<<"Person1 show"<<endl;
}
};
class Person2
{
public:
void showPerson2()
{
cout<<"Person2 show"<<endl;
}
};
template<class T>
class MyClass
{
public:
T obj;
//类模板中的成员函数
void func1()
{
obj.showPerson1();
}
void func2()
{
obj.showPerson2();
}
};
void test01()
{
MyClass<Person2>m;
//m.func1(); //编译会出错, 说明函数调用才会去创建成员函数
m.func2();
}
int main()
{
test01();
system("pause");
return 0;
}
🌼类模板对象作函数参数
#include<iostream>
using namespace std;
#include<typeinfo>
//类模板对象做函数参数
template<class T1, class T2>
class Person
{
public:
Person(T1 name, T2 age)
{
this->m_Name = name, this->m_Age = age;
}
void showPerson()
{
cout<<"姓名:"<<this->m_Name<<" 年龄:"<<this->m_Age<<endl;
}
T1 m_Name;
T2 m_Age;
};
//1,指定传入类型(最常用!)
void printPerson1(Person<string, int>&p) //引用传参
{
p.showPerson();
}
void test01()
{
Person<string, int>p("孙悟空", 99);
printPerson1(p);
}
//2,参数模板化
template<class T1, class T2>
void printPerson2(Person<T1, T2>&p)
{
p.showPerson();
cout<<"T1类型:"<<typeid(T1).name()<<endl; //查看模板退出来的类型
cout<<"T2类型:"<<typeid(T2).name()<<endl;
}
void test02()
{
Person<string, int>p("猪八戒", 55);
printPerson2(p);
}
//3,整个类模板化
template<class T> //告知编译器下面的T是什么
void printPerson3(T &p)
{
p.showPerson();
cout<<"T的类型:"<<typeid(T).name()<<endl;
}
void test03()
{
Person<string, int>p("唐僧", 23);
printPerson3(p);
}
int main()
{
//test01();
//test02();
test03();
system("pause");
return 0;
}
/*
总结
1, 类模板创建的对象, 3种方式向函数中传参
2, 开发中 指定传入类型 最常用
*/
🌼类模板与继承
#include<iostream>
using namespace std;
#include<typeinfo>
//类模板与继承
template<class T>
class Base //父类
{
public:
T m;
};
//class Son : public Base //× 需要知道父类中T的类型 子类才能继承
class Son : public Base<int> //√
{
};
void test01()
{
Son s1;
}
//如果想灵活指定父类中 T 的类型 子类也需要变成类模板
template<class T1, class T2>
class Son2 : public Base<T2>
{
public:
Son2()
{
cout<<"T1类型:"<<typeid(T1).name()<<endl;
cout<<"T2类型:"<<typeid(T2).name()<<endl;
}
T1 obj;
};
void test02()
{
Son2<int, char>S2; //int对应T1子类, char对应T2父类
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
/*
总结
如果父类时类模板 子类需要指定出父类中T的数据类型 才能继承
*/
🌳类模板成员函数类外实现
#include<iostream>
using namespace std;
//类模板成员函数类外实现
template<class T1, class T2>
class Person
{
public:
Person(T1 name, T2 age); //构造函数 类内声明
// {
// this->m_Name = name, this->m_Age = age;
// }
void showPerson(); //成员函数 类内声明
// {
// cout<<"姓名:"<<this->m_Name<<" 年龄:"<<m_Age<<endl;
// }
T1 m_Name; T2 m_Age;
};
//构造函数 类外实现
template<class T1, class T2> //让编译器知道T1 T2的存在
Person<T1, T2>::Person(T1 name, T2 age) //Person<T1, T2>是作用域, 表示类模板的类外实现
{
this->m_Name = name, this->m_Age = age;
}
//成员函数 类外实现
template<class T1, class T2>
void Person<T1, T2>::showPerson()
{
cout<<"姓名:"<<this->m_Name<<" 年龄:"<<m_Age<<endl;
}
void test01()
{
Person<string, int>p("Tom", 19);
p.showPerson();
}
int main()
{
test01();
system("pause");
return 0;
}
/*
总结
类模板成员函数类外实现时 需要加上 模板参数列表
*/
🌳类模板分文件编写
第1种("person.cpp"不常用)
main.cpp
#include<iostream>
using namespace std;
//类模板中成员函数 一开始不会创建
//第1种解决方式 直接包含源文件.cpp
//而.h头文件 只会让编译器看见 .h里的代码 里面没有实现 只有声明
//但是 .cpp头文件 让编译器先看完.cpp的代码 再通过.cpp中的.h头文件...
#include "person.cpp"
//第2种解决方式 .h和.cpp中内容写到一起 后缀名改为 .hpp文件
//.hpp 表示存在 类模板 hpp是认为规定的名称
//类模板分文件编写的问题 和 解决方法
//template<class T1, class T2>
//class Person
//{
//public:
//
// Person(T1 name, T2 age);
//
// void showPerson();
//
// T1 m_Name; T2 m_Age;
//};
//template<class T1, class T2>
//Person<T1, T2>::Person(T1 name, T2 age)
//{
// this->m_Name = name, this->m_Age = age;
//}
//
//template<class T1, class T2>
//void Person<T1, T2>::showPerson()
//{
// cout<<"姓名:"<<this->m_Name<<" 年龄:"<<m_Age<<endl;
//}
void test01()
{
Person<string, int>p("Jerry", 13);
p.showPerson();
}
int main()
{
test01();
system("pause");
return 0;
}
person.cpp
#include "person.h"
//类外实现放.cpp
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age)
{
this->m_Name = name, this->m_Age = age;
}
template<class T1, class T2>
void Person<T1, T2>::showPerson()
{
cout<<"姓名:"<<this->m_Name<<" 年龄:"<<m_Age<<endl;
}
person.h
//.h中开头包含的代码
#pragma once //防止头文件重复
#include<iostream> //标准输入输出流
using namespace std; //标准命名空间
template<class T1, class T2>
class Person
{
public:
Person(T1 name, T2 age);
void showPerson();
T1 m_Name; T2 m_Age;
};
第2种(.hpp常用)
main.cpp
#include<iostream>
using namespace std;
//类模板中成员函数 一开始不会创建
//第1种解决方式 直接包含源文件.cpp
//而.h头文件 只会让编译器看见 .h里的代码 里面没有实现 只有声明
//但是 .cpp头文件 让编译器先看完.cpp的代码 再通过.cpp中的.h头文件...
//#include "person.cpp"
#include "person.hpp"
//第2种解决方式 .h和.cpp中内容写到一起 后缀名改为 .hpp文件
//.hpp 表示存在 类模板 hpp是认为规定的名称
//类模板分文件编写的问题 和 解决方法
//template<class T1, class T2>
//class Person
//{
//public:
//
// Person(T1 name, T2 age);
//
// void showPerson();
//
// T1 m_Name; T2 m_Age;
//};
//template<class T1, class T2>
//Person<T1, T2>::Person(T1 name, T2 age)
//{
// this->m_Name = name, this->m_Age = age;
//}
//
//template<class T1, class T2>
//void Person<T1, T2>::showPerson()
//{
// cout<<"姓名:"<<this->m_Name<<" 年龄:"<<m_Age<<endl;
//}
void test01()
{
Person<string, int>p("Jerry", 13);
p.showPerson();
}
int main()
{
test01();
system("pause");
return 0;
}
person.hpp
person.h 和 person.cpp放一块
//.h中开头包含的代码
#pragma once //防止头文件重复
#include<iostream> //标准输入输出流
using namespace std; //标准命名空间
template<class T1, class T2>
class Person
{
public:
Person(T1 name, T2 age); //类内声明
void showPerson(); //类内声明
T1 m_Name; T2 m_Age;
};
//类外实现放.cpp
template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age)
{
this->m_Name = name, this->m_Age = age;
}
template<class T1, class T2>
void Person<T1, T2>::showPerson()
{
cout<<"姓名:"<<this->m_Name<<" 年龄:"<<m_Age<<endl;
}
总结
主流解决方法,将类模板成员函数的声明和实现写到一起,并将后缀名改为 .hpp
🌳类模板与友元
全局函数类内实现:直接类内friend声明友元
全局函数类外实现:提前让编译器知道全局函数存在
由于类外实现较为复杂,一般类内实现,用法简单,编译器可直接识别
#include<iostream>
using namespace std;
//通过 全局函数 打印Person信息
//1,
template<class T1, class T2> //这个类是模板的
class Person; //让编译器知道有Person存在
//2, 1放2前面, 2放后面的实现前面
//类外实现
template<class T1, class T2>
void printPerson2(Person<T1, T2>p) //前面需要先让编译器知道Person存在
{
cout<<"类外实现: 姓名:"<<p.m_Name<<" 年龄:"<<p.m_Age<<endl;
}
template<class T1, class T2>
class Person
{
public:
//全局函数 类内实现
friend void printPerson(Person<T1, T2> p) //参数模板化 ; 友元可以访问私有属性
{
cout<<"姓名:"<<p.m_Name<<" 年龄:"<<p.m_Age<<endl;
}
//全局函数 类外实现
//加个空模板参数列表 <> 告诉编译器这不是普通函数 是模板函数
//全局函数类外实现的话 需要让编译器提前知道这个函数的存在
friend void printPerson2<>(Person<T1, T2>p);
Person(T1 name, T2 age)
{
this->m_Name = name, this->m_Age = age;
}
private:
T1 m_Name; T2 m_Age;
};
//全局函数 类内实现
void test01()
{
Person<string, int>p("Tom", 22);
printPerson(p);
}
//2,全局函数 类外实现
void test02()
{
Person<string, int>p("Jerry", 33);
printPerson2(p);
}
int main()
{
test01();
test02();
return 0;
}
🍌类模板案例 -- 数组类封装
代码1
MyArray.hpp
//自己通用的数组类
#pragma once
#include<iostream>
using namespace std;
template<class T>
class MyArray
{
public:
//有参构造 参数 容量
MyArray(int capacity)
{
cout<<"MyArray 有参 构造调用"<<endl;
this->m_Capacity = capacity; //容量
this->m_Size = 0; //大小
this->pAddress = new T[this->m_Capacity]; //堆区数据, new一个数组
}
//拷贝构造 防止浅拷贝
MyArray(const MyArray& arr)
{
cout<<"MyArray 拷贝 构造调用"<<endl;
this->m_Capacity = arr.m_Capacity;
this->m_Size = arr.m_Size;
//this->pAddress = arr.pAddress; //浅拷贝会导致堆区数据重复释放
//深拷贝
this->pAddress = new T[arr.m_Capacity]; //堆区开辟数据
//将arr中数据拷贝过来
for(int i = 0; i < this->m_Size; ++i) {
this->pAddress[i] = arr.pAddress[i];
}
}
//operator= 防止浅拷贝问题 a = b = c 等号赋值时 自身引用 以便连等
MyArray& operator=(const MyArray& arr)
{
cout<<"MyArray operator= 调用"<<endl;
//先判断原来堆区是否有数据, 有就先释放
if(this->pAddress != NULL) {
delete[] this->pAddress;
this->pAddress = NULL;
this->m_Capacity = 0;
this->m_Size = 0;
}
//深拷贝
this->m_Capacity = arr.m_Capacity;
this->m_Size = arr.m_Size;
this->pAddress = new T[arr.m_Capacity];
for(int i = 0; i < this->m_Size; ++i) {
this->pAddress[i] = arr.pAddress[i];
}
return *this; //返回自身
}
//析构函数 手动开辟 手动释放
~MyArray()
{
cout<<"MyArray 析构 函数调用"<<endl;
if(this->pAddress != NULL) {
delete[] this->pAddress;
this->pAddress = NULL; //防止野指针
}
}
private:
T * pAddress; //指针指向堆区开辟的真实数组
int m_Capacity; //数组容量
int m_Size; //数组大小
};
测试1.cpp
#include<iostream>
using namespace std;
#include "MyArray.hpp"
void test01()
{
MyArray <int>arr1(5); //缺<int>会报错missing template argument
MyArray <int>arr2(arr1); //拷贝构造
MyArray <int>arr3(100); //容量100
arr3 = arr1; //先清空100 再拷贝arr1
}
int main()
{
test01();
system("pause");
return 0;
}
输出
MyArray 有参 构造调用
MyArray 拷贝 构造调用
MyArray 有参 构造调用
MyArray operator= 调用
MyArray 析构 函数调用
MyArray 析构 函数调用
MyArray 析构 函数调用
请按任意键继续. . .
代码2
MyArray.hpp
//自己通用的数组类
#pragma once
#include<iostream>
using namespace std;
template<class T>
class MyArray
{
public:
//构造函数
MyArray(int capacity)
{
this->m_Capacity = capacity; //容量
this->m_Size = 0; //大小
this->pAddress = new T[this->m_Capacity]; //堆区数据, new一个数组
}
//拷贝构造
MyArray(const MyArray& arr)
{
this->m_Capacity = arr.m_Capacity;
this->m_Size = arr.m_Size;
//浅拷贝会导致堆区数据重复释放
//this->pAddress = arr.pAddress;
//深拷贝
this->pAddress = new T[arr.m_Capacity]; //堆区开辟数据
//将arr中数据拷贝过来
for(int i = 0; i < this->m_Size; ++i) {
this->pAddress[i] = arr.pAddress[i];
}
//如果 T 为对象 且包含指针 必须重载 = 操作符
//普通类型可以直接 = , 指针类型需要深拷贝
}
//operator= 防止浅拷贝问题 a = b = c 等号赋值时 自身引用 以便连等
//重载 = 操作符 防止浅拷贝问题
MyArray& operator=(const MyArray& arr)
{
//先判断原来堆区是否有数据, 有就先释放
if(this->pAddress != NULL) {
delete[] this->pAddress;
this->pAddress = NULL;
this->m_Capacity = 0;
this->m_Size = 0;
}
//深拷贝
this->m_Capacity = arr.m_Capacity;
this->m_Size = arr.m_Size;
this->pAddress = new T[arr.m_Capacity];
for(int i = 0; i < this->m_Size; ++i) {
this->pAddress[i] = arr.pAddress[i];
}
return *this; //返回自身
}
//尾插法
void Push_Back(const T & val)
{
//判断容量是否等于大小
if(this->m_Capacity == this->m_Size) {
return;
}
this->pAddress[this->m_Size] = val; //数组末尾插入value
this->m_Size++; //更新数组大小
}
//尾删法
void Pop_Back()
{
//让用户访问不到最后一个元素 即尾删, 逻辑上的删除
if(this->m_Size == 0)
return;
this->m_Size--;
}
//通过下标方式访问数组中元素
//重载 [], 以便能通过下标访问
T& operator[] (int index) //T的引用 使函数调用可以作为左值存在
{ //比如arr[0] = 100;
return this->pAddress[index];
}
//返回数组容量
int getCapacity()
{
return this->m_Capacity;
}
//返回数组大小
int getSize()
{
return this->m_Size;
}
//析构函数 手动开辟 手动释放
~MyArray()
{
if(this->pAddress != NULL) {
delete[] this->pAddress;
this->pAddress = NULL; //防止野指针
}
}
private:
T * pAddress; //指针指向堆区开辟的真实数组
int m_Capacity; //数组容量
int m_Size; //数组大小
};
测试1.cpp
#include<iostream>
using namespace std;
#include "MyArray.hpp"
void printIntArray(MyArray <int>& arr)
{
for(int i = 0; i < arr.getSize(); ++i) {
cout<<arr[i]<<endl;
}
}
void test01()
{
MyArray <int>arr1(5); //缺<int>会报错missing template argument
for(int i = 0; i < 5; ++i) {
//尾插法 向数组中插入数据
arr1.Push_Back(i);
}
cout<<"arr1的打印输出:"<<endl;
printIntArray(arr1);
cout<<"arr1的容量:"<<arr1.getCapacity()<<endl;
cout<<"arr1的大小:"<<arr1.getSize()<<endl;
MyArray <int>arr2(arr1);
cout<<"arr2的打印输出:"<<endl;
printIntArray(arr2);
//尾删
arr2.Pop_Back();
cout<<"arr2的容量:"<<arr2.getCapacity()<<endl;
cout<<"arr2的大小:"<<arr2.getSize()<<endl;
// MyArray <int>arr2(arr1); //拷贝构造
//
// MyArray <int>arr3(100); //容量100
// arr3 = arr1; //先清空100 再拷贝arr1
}
//测试自定义数据类型
class Person
{
public:
Person() {};
Person(string name, int age)
{
this->m_Name = name;
this->m_Age = age;
}
string m_Name;
int m_Age;
};
void printPersonArray(MyArray<Person>& arr)
{
for(int i = 0; i < arr.getSize(); ++i) {
cout<<"姓名:"<<arr[i].m_Name<<" 年龄:"<<arr[i].m_Age<<endl;
}
}
void test02()
{
MyArray<Person>arr(10);
Person p1("孙悟空",999);
Person p2("程咬金",17);
Person p3("妲己",45);
Person p4("亚瑟",234);
Person p5("小巧",89);
Person p6("大哥",12);
//数据插入到数组中
arr.Push_Back(p1);
arr.Push_Back(p2);
arr.Push_Back(p3);
arr.Push_Back(p4);
arr.Push_Back(p5);
arr.Push_Back(p6);
//打印数组
printPersonArray(arr);
//输出容量
cout<<"arr容量:"<<arr.getCapacity()<<endl;
//输出大小
cout<<"arr大小:"<<arr.getSize()<<endl;
}
int main()
{
//test01();
test02();
system("pause");
return 0;
}
输出
姓名:孙悟空 年龄:999
姓名:程咬金 年龄:17
姓名:妲己 年龄:45
姓名:亚瑟 年龄:234
姓名:小巧 年龄:89
姓名:大哥 年龄:12
arr容量:10
arr大小:6
请按任意键继续. . .
🥕总结
学了一些一些模板封装,真要自己手写,也只能写出小部分简单的,稍微复杂一点的肯定各种bug,没事,后续还有《Essential C++》和《算法训练营》的查漏补缺
题外话
今天群里碰到个人,自己大一408和数据库学完了,现在在读研,结果劝人不要学习,学的再好出来也大概率月入3000,这种人,不是蠢,就是坏,总之各种打击萌新,太可恶了!
一有萌新出来,就各种打击,各种看不起,可恶
“学这没用”,“学这点东西差远了”,“没机会的”,“别学了,学再多也是失业”,“现在学会了,过几年又更新换代了,放弃吧”,“使劲卷,卷到大四看到你们找不到工作哈哈”(神经病😂)
它说什么不是重点,重点是它成功打击到别人,满足了内心的欲望,借机释放自己的压力和负面情绪