C++ STL库学习
一、模板
1. 函数模板
#include <iostream>
using namespace std;
//模板技术:类型参数化,编写代码可以忽略类型
//为了让编译器区分普通函数 模板函数
//template只对第一个函数生效
template<typename T> //template<class T>
void MySwap(T& a,T& b){
T temp = a;
a = b;
b = temp;
}
int main(){
int a = 10;
int b = 12;
// 1 自动类型推导
MySwap(a,b);
cout << "a = " << a << " b = " << b << endl;
// 2 显式的指定类型
MySwap<int>(a,b);
cout << "a = " << a << " b = " << b << endl;
return 0;
}
1.1 函数模板和普通函数的区别
- 函数模板不允许自动类型转化;
- 普通函数能够进行自动类型转化;
【函数模板和普通函数在一起调用规则】
- 函数模板可以像普通函数一样被重载;
- C++编译器有限考虑普通函数;
- 如果函数模板可以产生一个更好的匹配,那么选择模板;
- 可以通过空模板实参列表的语法限定编译器只能通过模板匹配;
// 函数重载示例
#include <iostream>
using namespace std;
//模板技术:类型参数化,编写代码可以忽略类型
template<typename T>
void MySwap(T& a,T& b){
T temp = a;
a = b;
b = temp;
}
// 函数模板的重载
template<typename T> //template<class T>
void MySwap(T& a,T& b, T& c){
T temp = a;
a = b;
b = c;
c = temp;
}
int main(){
int a = 10;
int b = 12;
int c = 11;
MySwap(a,b);
cout << "a = " << a << " b = " << b << " c = " << c << endl;
MySwap(a,b,c);
cout << "a = " << a << " b = " << b << " c = " << c << endl;
return 0;
}
1.2 C++函数模板机制剖析
【函数模板与模板函数】
【函数模板机制结论】
- 编译器并不是把函数模板处理成能够处理任何类型的函数;
- 函数模板通过具体类型产生不同的函数;
- 编译器会对函数模板进行再次编译,在声明的地方对模板代码本身进行编译,在调用的地方对参数替换后的代码进行编译;
1.3 函数模板案例—char、int类型数组排序
#include <iostream>
using namespace std;
//对char类型和Int类型数组进行排序
//打印函数
template<class T>
void PrintArray(T* arr,int len){
for(int i = 0;i < len;i++) cout << arr[i] << " ";
cout << endl;
}
//排序
template<class T>
void MySort(T* arr,int len){
for(int i= 0;i < len;i++){
for(int j = i+1;j < len;j++){
//从小到大排序
if(arr[i] < arr[j]) swap(arr[i],arr[j]);
}
}
}
int main(void)
{
//数组
int arr[] = {
2,6,1,8,9,2};
//数组长度
int len = sizeof(arr)/sizeof(int);
cout << "排序之前" << endl;
PrintArray(arr,len);
// 排序
MySort(arr,len);
cout << "排序之后" << endl;
PrintArray(arr,len);
cout << "---------------------" << endl;
char chArr[] = {
'a','c','b','p','t'};
len = sizeof(chArr)/sizeof(char);
cout << "排序之前" << endl;
PrintArray(chArr,len);
// 排序
MySort(chArr,len);
cout << "排序之后" << endl;
PrintArray(chArr,len);
return 0;
}
2. 类模板
2.1 类模板基本语法
#include <iostream>
using namespace std;
// 1 类模板定义
template<class T>
class Person{
public:
Person(T id,T age){
this->mAge = age;
this->mID = id;
}
void Show(){
cout << "ID:" << mID << " Age:" << mAge << endl;
}
public:
T mID;
T mAge;
};
// 2 类模板调用
void test01(){
// 函数模板在调用的时候,可以自动类型推导
// 类模板必须显式制定类型
Person<int> p(10,20);
p.Show();
}
int main(){
test01();
return 0;
}
2.2 类模板案例—类模板派生普通类
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
template<class T>
class Person{
public:
Person(){
mAge = 0;
}
public:
T mAge;
}
//为什么?
//类去定义对象,这个对象需要分配内存,因此需要指定类型
class SubPerson : public Person<int>{
}
2.3 类模板案例—类模板派生类模板
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
template<class T>
class Animal{
public:
void talking(){
cout << mAge << " 岁动物在叫!" << endl;
}
public:
T mAge;
};
template<class T>
class Cat : public Animal<T>{
};
int main(void)
{
Cat<int> cat;
cat.talking();
return 0;
}
3. 普通类.h 与 .cpp分离编写方式
//.h中仅仅做类的声明 Person.h
#ifndef PERSON_H //防止头文件被重复包含
#define PERSON_H
#endif
//.h中仅仅做类的声明 Person.h
#pragma once // 防止头文件被重复包含
#include<iostream>
#include<string>
class Person{
public:
Person(String name ,int age);
void Show();
public:
string mName;
int mAge;
int mID;
}
//Person.cpp
#include "Person.h"
Person::Person(string name,int age){
this->mName = name;
this->mAge = age;
}
void Person::show(){
cout << "Name:" << this->mName << " Age:" << this->mAge << endl;
}
//main.cpp
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include "Person.h"
int main(void){
Person p("AAA",20);
p.show();
return 0;
}
4 类模板中函数的实现
4.1 在类内进行实现
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>