内存分区模型、引用的基本语法、三种参数传递方式、引用的本质、const修饰参数防止被修改、函数默认值、占位参数、函数重载、面向对象、浅拷贝带来问题、友元、运算符重载、继承、文件读写、模板、STL、函数对象、算法
内存分区模型
c++程序在执行中,将内存分为4个区域
- 代码区:存放函数体的二进制代码,由操作系统进行管理
- 全局区:存放全局变量和静态变量以及常量
- 栈区:由编译器自动分配释放,存放函数的函数值,局部变量等
- 堆区:由程序员分配和释放,若程序员不释放,程序结束后由操作系统回收
注意事项:
- 不要返回局部变量的地址
- 堆区数据利用new关键字进行开辟,使用完需要手动释放,用delete关键字
- 数组类型数据释放内存,delete[],如果只用delete只会释放数据的第一数据的内存
引用的基本语法
#include <iostream>
using namespace std;
void main() {
int a = 10;
int &b = a;
cout << (int) & a << endl;
cout << (int) & b << endl;
}
注意:
- 引用必须初始化
- 一旦初始化后就不允许进行改变
三种参数传递方式
#include <iostream>
using namespace std;
void swap01(int a,int b) {
int temp = a;
a = b;
b = temp;
}
void swap02(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void swap03(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
void main() {
int a;
int b;
a = 10;
b = 20;
//1.值传递
//形参不会修饰实参
swap01(a, b);
cout << a << endl;
cout << b << endl;
a = 10;
b = 20;
//2.地址传递
//形参会修饰实参
swap02(&a, &b);
cout << a << endl;
cout << b << endl;
a = 10;
b = 20;
//3.引用传递
//形参会修饰实参
swap03(a, b);
cout << a << endl;
cout << b << endl;
}
引用的本质
#include <iostream>
using namespace std;
//发现是引用,转换成 int* const ref = &a;
void func(int& ref) {
ref = 100; //ref是引用,转换成*ref=100
}
void main() {
int a = 10;
//自动转换成int* const ref = &a;指针常量是指针指向不可改,也说明为什么引用不可更改
int& ref = a;
ref = 20; //ref是引用,转换成*ref=20
cout << "a:" << a << endl;
cout << "ref:" << ref << endl;
func(a);
}
const修饰参数防止参数被修改
#include <iostream>
using namespace std;
//引用使用的场景,通常用来修饰形参,防止形参被修改
void showValue(const int& v) {
//v += 10; 不可以修改
cout << v << endl;
}
void main() {
//编译器优化 int temp = 10;const int& ref = temp;
const int& ref = 10;
int a = 10;
showValue(10);
}
函数默认值
#include <iostream>
using namespace std;
//1.如果某个位置参数有默认值,那么从这个位置往后,必须都要有默认值
//2.如果函数声明有默认值,函数实现的时候就不能有默认参数
int func(int a, int b = 10, int c = 1);
int func(int a, int b, int c) {
return a + b + c;
}
void main() {
int res = func(1);
cout << res << endl;
}
占位参数
#include <iostream>
using namespace std;
//占位参数如果没有默认值,调用时必传
int func(int a, int, int =10) {
return a;
}
void main() {
int res = func(1,1);
cout << res << endl;
}
函数重载
- 同一个作用域下
- 函数名相同
- 参数类型不同,或者个数不同,或者顺序不同
- 函数的返回值不可以作为函数重载的条件
#include <iostream>
using namespace std;
//引用重载案例
int func(int &a) {//int &a = 10;不合法
return a;
}
int func(const int& a) {
return a;
}
void main() {
int res = func(1);//走第二个函数
cout << res << endl;
}
面向对象
创建类并实例化
#include <iostream>
using namespace std;
class Circle {
public:
int r;
double getRound() {
return 2 * 3.14 * r;
}
};
void main() {
//实例化
Circle circle;
circle.r = 10;
cout << circle.getRound() << endl;
}
构造方法
- 分为有参、无参、拷贝,必须是public修饰的方法,方法名和类名一致
- 调用无参构造方法创建对象时,不要用括号方式,因为编译器会把它当作是一个函数的声明
- 不要利用拷贝构造函数初始化匿名对象,编译器会认为是 Person(p3) 等价于 Person p3;
```
#include
#include
using namespace std;
class Person { private: string name; public: Person() { cout « “无参构造函数执行” « endl; } Person(int a) { cout « “有参构造函数执行” « endl; } Person(const Person& p) { cout « “拷贝构造函数执行” « endl; name = p.name; } ~Person() { cout « “析构函数执行” « endl; } };
void main() { //显式法 Person p1; Person p2 = Person(10);//有参构造 Person p3 = Person(p2);//拷贝构造
Person(10);//匿名对象,执行结束后立马被析构掉
//隐式法
Person p4 = 10;//相当于Person p4 = Person(10)
Person p5 = p4;//相当于Person p5 = Person(p4) } ``` ## 构造函数调用规则 默认情况下,c++编译器至少给一个类加3个函数 1.默认构造函数(无参,函数体为空) 2.默认析构函数(无参,函数体为空) 3.默认拷贝构造函数
构造函数调用规则如下:
- 如果用户定义有参构造函数,c++不再提供默认无参构造,但是会提供默认拷贝构造
- 如果用户定义拷贝构造函数,c++不再提供其他构造函数
浅拷贝带来的问题
对象中存在堆申请空间的代码,其复制的对象和原对象指向堆中同一个对象,在堆区数据释放时会重复释放导致报错,所以对象中包含在堆区申请空间的代码,应该手动创建拷贝构造函数,将浅拷贝变成深拷贝
类的初始化列表
#include <iostream>
using namespace std;
class Person{
public:
int a;
int b;
int c;
Person(int a,int b,int c):a(a),b(b),c(c)
{
}
};
int main()
{
Person person(10,20,30);
std::cout << person.a << endl;
std::cout << person.b << endl;
std::cout << person.c << endl;
return 0;
}
类对象作为成员
#include <iostream>
#include <string>
using namespace std;
class Phone{
public:
string name;
Phone(string name){
this->name = name;
}
};
class Person{
public:
string name;
//当其他对象作为本类成员时。先构成其他类对象,再构造本类对象,析构顺序相反
Phone phone;
Person(string name,string phone):name(name),phone(phone)
{
}
};
int main()
{
Person person("zhang","IPhoneX");
std::cout << person.name << endl;
std::cout << person.phone.name << endl;
return 0;
}
静态成员
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
//静态变量所有对象共享,可以通过对象访问也可以通过类直接访问
static int a;
};
int Person::a = 1;//声明方式初始化静态属性
int main()
{
Person::a = 10;
std::cout << Person::a << endl;
return 0;
}
常函数和常对象
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
//this本质是指针常量 Person * const this 指针指向不可以修改
//const 修饰的成员函数,修饰的是 this 相当于 const Person * const this,this指向的值也不可以修改
void showPerson() const
{
//this->name = "zhanghuan1"; 不可执行
this->a = 10; //该成员属性使用mutable修饰,故可以修改
}
void func(){
}
Person(){
}
mutable int a;
string name;
};
int main()
{
Person p;
p.showPerson();
std::cout << p.name << endl;
std::cout << p.a << endl;
//定义常对象
const Person p1;
p1.showPerson();//只能执行常函数
//p1.func();无法执行
return 0;
}
友元
全局函数作友元
#include <iostream>
#include <string>
using namespace std;
class Building{
//将全局函数做友元
friend void goodGay(Building *building);
public:
Building(){
this->meetingRoom = "客厅";
this->bedRoom = "卧室";
}
string meetingRoom;
private:
string bedRoom;
};
//全局函数
void goodGay(Building *building){
cout << "好基友在访问" << building->meetingRoom << endl;
cout << "好基友在访问" << building->bedRoom << endl;//可访问私有属性
}
int main()
{
Building building;
goodGay(&building);
return 0;
}
类作为友元
#include <iostream>
#include <string>
using namespace std;
class Building{
//将类做友元
friend class GoodGay;
public:
Building(){
this->meetingRoom = "客厅";
this->bedRoom = "卧室";
}
string meetingRoom;
private:
string bedRoom;
};
class GoodGay{
public:
Building *building;
GoodGay(){
this->building = new Building;
}
void visit(){
cout << "好基友在访问" << building->meetingRoom << endl;
cout << "好基友在访问" << building->bedRoom << endl;//可访问私有属性
}
};
int main()
{
GoodGay goodGay;
goodGay.visit();
return 0;
}
成员函数作友元
#include <iostream>
#include <string>
using namespace std;
class Building;
class GoodGay{
public:
Building *building;
GoodGay();
void visit();
};
class Building{
//将成员函数做友元
friend void GoodGay::visit();
public:
Building();
string meetingRoom;
private:
string bedRoom;
};
void GoodGay::visit(){
cout << "好基友在访问" << building->meetingRoom << endl;
cout << "好基友在访问" << building->bedRoom << endl;//可访问私有属性
}
GoodGay::GoodGay(){
this->building = new Building;
}
Building::Building(){
this->meetingRoom = "客厅";
this->bedRoom = "卧室";
}
int main()
{
GoodGay goodGay;
goodGay.visit();
return 0;
}
运算符重载
加号运输符重载
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
Person(){
}
Person(int a):a(a){
}
//成员函数重载加号
Person operator+(Person p){
int temp = p.a + this->a;
Person p1;
p1.a = temp;
return p1;
}
int a;
};
class Man{
public:
Man(){
}
Man(int a){
this->a = a;
}
int a;
};
//全局函数重载加号
Man operator+(Man &man1,Man &man2){
int temp = man1.a + man2.a;
Man man(temp);
return man;
}
//运算符重载也可以函数重载
Man operator+(Man &man1,int num){
int temp = man1.a + num;
Man man(temp);
return man;
}
int main()
{
Person p1(10);
Person p2(20);
Person p3 = p1 + p2;
cout << p3.a << endl;
Man man1(10);
Man man2(20);
Man man3 = man1 + man2;
cout << man3.a << endl;
Man man4 = man3 + 20;
cout << man4.a << endl;
return 0;
}
左移运算符重载
#include <iostream>
#include <string>
using namespace std;
class Person{
friend ostream& operator<<(ostream &cout,Person &p);
public:
Person(){
}
Person(int a,int b){
this->a = a;
this->b = b;
}
private:
int a;
int b;
};
//重载左移运算符
ostream& operator<<(ostream &cout,Person &p){
cout << "a=" << p.a << ",b=" << p.b;
return cout;
}
int main()
{
Person p(10,20);
cout << p << endl;
return 0;
}
递增运算符重载
#include <iostream>
#include <string>
using namespace std;
class MyInteger{
friend ostream& operator<<(ostream& cout,MyInteger myInteger);
public:
MyInteger(){
this->num = 0;
}
MyInteger(int num){
this->num = num;
}
//定义前置递增
MyInteger& operator++(){
this->num++;
return *this;
}
//定义后置递增
MyInteger operator++(int){
//拷贝构造函数创建一个新对象
MyInteger temp = *this;
this->num++;
return temp;
}
private:
int num;
};
ostream& operator<<(ostream& cout,MyInteger myInteger){
cout << myInteger.num;
return cout;
}
int main()
{
MyInteger myInteger(10);
cout << myInteger << endl;
cout << ++myInteger << endl; //11
cout << myInteger++ << endl; //11
return 0;
}
赋值运算符重载
#include <iostream>
#include <string>
using namespace std;
class MyInteger{
friend ostream& operator<<(ostream& cout,MyInteger& myInteger);
public:
MyInteger(){
this->num = new int(0);
}
MyInteger(int num){
this->num = new int(num);
}
~MyInteger(){
if(this->num != NULL){
delete this->num;
this->num = NULL;
}
}
MyInteger& operator=(MyInteger& myInteger){
//清空
if(this->num != NULL){
delete this->num;
this->num = NULL;
}
//深拷贝
this->num = new int(*myInteger.num);
return *this;
}
private:
int *num;
};
ostream& operator<<(ostream& cout,MyInteger& myInteger){//myInteger如果不传指向析构函数会执行两次,除非重写拷贝构造函数
cout << *myInteger.num;
return cout;
}
int main()
{
MyInteger myInteger1(10);
MyInteger myInteger2(20);
MyInteger myInteger3(30);
myInteger3 = myInteger2 = myInteger1;
cout << myInteger1 << endl;
cout << myInteger2 << endl;
cout << myInteger3 << endl;
return 0;
}
关系运算符重载
#include <iostream>
#include <string>
using namespace std;
class Person{
public:
Person(string name){
this->name = name;
}
bool operator==(Person& person){
if(person.name == this->name){
return true;
}
return false;
}
bool operator!=(Person& person){
if(person.name != this->name){
return true;
}
return false;
}
string name;
};
int main()
{
Person p1("zhang");
Person p2("zhang1");
std::cout << (p1 == p2) << endl; //0
std::cout << (p1 != p2) << endl; //1
return 0;
}
函数调用运算符重载
#include <iostream>
#include <string>
using namespace std;
class Myadd{
public:
int operator()(int a,int b){
return a + b;
}
};
int main()
{
Myadd myadd1;
int res1 = myadd1(10,10);
cout << res1 << endl;
//匿名对象调用
cout << Myadd()(10,20) << endl;
return 0;
}
继承
三种继承方式
#include <iostream>
#include <string>
using namespace std;
class Base{
public:
Base(){
a = 10;
b = 20;
c = 30;
}
int a;
protected:
int b;
private:
int c;
};
//3中继承方式
class Son1:public Base{
//继承过来的所有公共属性仍然为公共属性
};
class Son2:protected Base{
//继承过来的所有公共属性变成保护属性
};
class Son3:private Base{
//继承过来的所有公共属性、保护属性都变成私有属性
};
int main()
{
Son1 son1;
cout << son1.a << endl;
return 0;
}
同名属性访问
#include <iostream>
#include <string>
using namespace std;
class Base{
public:
Base(){
a = 10;
b = 20;
c = 30;
}
int a;
protected:
int b;
private:
int c;
};
class Son:public Base{
public:
Son(){
a = 110;
}
int a;
};
int main()
{
Son son;
//默认访问子类的属性a
cout << son.a << endl;
//范围父类的属性a
cout << son.Base::a << endl;
return 0;
}
多继承语法
#include <iostream>
#include <string>
using namespace std;
class Base1{
public:
Base1(){
a = 10;
}
int a;
};
class Base2{
public:
Base2(){
a = 20;
}
int a;
};
//多继承语法
class Son:public Base1,public Base2{
public:
Son(){
a = 110;
}
int a;
};
int main()
{
Son son;
cout << son.a << endl;
cout << son.Base1::a << endl;
cout << son.Base2::a << endl;
return 0;
}
菱形继承
#include <iostream>
#include <string>
using namespace std;
class Animal{
public:
int a;
};
//通过虚继承解决子类继承的a属性的指向不明问题
class Sheep:virtual public Animal{
};
class Tuo:virtual public Animal{
};
class SheepTuo:public Sheep,public Tuo{
};
int main()
{
SheepTuo sheepTuo;
sheepTuo.a = 1;
cout << sheepTuo.Sheep::a << endl; //1
cout << sheepTuo.Tuo::a << endl; //1
cout << sheepTuo.a << endl; //1
return 0;
}
多态
多态分两类
- 静态多态:函数重载和运算符重载属于静态多态,复用函数名
- 动态多态:派生类和虚函数实现运行时多态
静态多态和动态多态区别
- 静态多态的函数地址早绑定,编译阶段确定函数地址
- 动态多态的函数地址晚绑定,运行阶段确定函数地址
#include <iostream>
#include <string>
using namespace std;
class Animal{
public:
//使用虚函数
virtual void speak(){
cout << "动物在说话" << endl;
}
};
class Cat:public Animal{
public:
void speak(){
cout << "猫在说话" << endl;
}
};
class Dog:public Animal{
public:
void speak(){
cout << "狗在说话" << endl;
}
};
void doSpeak(Animal &animal){
animal.speak();
}
int main()
{
Cat cat;
doSpeak(cat); //猫在说话
Dog dog;
doSpeak(dog); //狗在说话
return 0;
}
虚函数原理
类中有虚函数,内的内部会有一个虚函数表记录虚函数的地址,当子类重写父类的虚函数时,子类的虚函数表内部会替换成子类函数的地址,从而实现多态
纯虚函数
语法 virtual 返回值类型 虚函数名 (参数列表) = 0
但类中有了纯虚函数,这个类就是抽象类
抽象类特点
- 无法实例化对象
- 子类必须重写抽象类中的虚函数,否则也属于抽象类
虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么弗雷指针子啊释放时无法调用到子类的析构代码,导致内存泄漏 解决方式:将父类中的析构函数改为虚析构或者纯虚析构
案例
#include <iostream>
#include <string>
using namespace std;
class Cpu{
public:
virtual void calculate() = 0;
virtual ~Cpu(){};
};
class DisplayCard{
public:
virtual void display() = 0;
virtual ~DisplayCard(){};
};
class Storage{
public:
virtual void store() = 0;
virtual ~Storage(){};
};
class IntelCpu:public Cpu{
public:
virtual void calculate(){
cout << "IntelCpu 开始计算" << endl;
}
~IntelCpu(){
cout << "IntelCpu 析构函数执行" <<endl;
}
};
class NvdCard:public DisplayCard{
public:
virtual void display(){
cout << "NvdCard 开始工作" << endl;
}
~NvdCard(){
cout << "NvdCard 析构函数执行" <<endl;
};
};
class SamSungDisk:public Storage{
public:
virtual void store(){
cout << "三星硬盘 开始工作" << endl;
}
~SamSungDisk(){
cout << "三星硬盘 析构函数执行" <<endl;
};
};
class Computer{
public:
Computer(Cpu *cpu,DisplayCard *displayCard,Storage *storage){
this->cpu = cpu;
this->displayCard = displayCard;
this->storage = storage;
}
void doWork(){
cpu->calculate();
displayCard->display();
storage->store();
}
~Computer(){
cout << "Computer 析构函数执行" << endl;
if(cpu != NULL){
delete cpu;
cpu = NULL;
}
if(displayCard != NULL){
delete displayCard;
displayCard = NULL;
}
if(storage != NULL){
delete storage;
storage = NULL;
}
}
private:
Cpu *cpu;
DisplayCard *displayCard;
Storage *storage;
};
int main()
{
Computer *computer = new Computer(new IntelCpu(),new NvdCard(),new SamSungDisk());
computer->doWork();
delete computer;
/**
* IntelCpu 开始计算
NvdCard 开始工作
三星硬盘 开始工作
Computer 析构函数执行
IntelCpu 析构函数执行
NvdCard 析构函数执行
三星硬盘 析构函数执行
* /
return 0;
}
文件读写
普通方式文件读写
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void test1() {
//写入
ofstream ofs;
ofs.open("test.txt", ios::out);
ofs << "姓名:张三" << endl;
ofs << "性别:男" << endl;
ofs << "年龄:23" << endl;
ofs.close();
}
void test2() {
//读取
ifstream ifs;
ifs.open("test.txt", ios::in);
if (!ifs.is_open()) {
cout << "文件打开失败" << endl;
return;
}
char buf[1024] = { 0 };
//方式一
/**
while (ifs >> buf) {
cout << buf << endl;
}
**/
//方式二
/**
while (ifs.getline(buf, sizeof(buf))) {
cout << buf << endl;
}
**/
//方式三
/**
string bf;
while (getline(ifs, bf)) {
cout << bf << endl;
}
**/
//方式四
char c;
while ( (c = ifs.get()) != EOF) {
cout << c;
}
ifs.close();
}
void main() {
test2();
}
二进制方式读写
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
class Person {
public:
string name;
int age;
};
void test1() {
//写入
ofstream ofs;
ofs.open("person.txt", ios::out | ios::binary);
Person p = { "zhanghuan",22 };
ofs.write((const char*)&p, sizeof(p));
ofs.close();
}
void test2() {
//读取
ifstream ifs;
ifs.open("person.txt", ios::in | ios::binary);
if (!ifs.is_open()) {
cout << "文件打开失败" << endl;
return;
}
Person p;
ifs.read((char*)&p, sizeof(Person));
cout << p.name << endl;
cout << p.age << endl;
ifs.close();
}
int main() {
//test1();
test2();
return 0;
}
模板
基本使用
#include <cstdio>
template<typename T>
void swap(T &a, T &b)
{
T t = a;
a = b;
b = t;
}
int main()
{
int x = 3, y = 6;
printf("%d %d\n", x, y);
swap<int>(x, y);//制定类型,可不传int则会自动推导
printf("%d %d\n", x, y);
return 0;
}
注意事项
- 自动类型推导,必须推导出一致数据类型T才可以使用
- 模板必须要确定出T的数据类型,才可以使用
选择排序案例
#include <cstdio>
template<typename T>
void swap(T &a, T &b)
{
T t = a;
a = b;
b = t;
}
template<typename T>
void printArray(T arr[],int len){
printf("[");
for (int i = 0; i < len; ++i) {
printf("%d", arr[i]);
if (i < len - 1) {
printf(", ");
}
}
printf("]\n");
}
template<typename T>
void mySort(T arr[],int len){
for(int i=0;i<len;i++){
int maxIndex = i;
for (int j = i+1; j < len; j++) {
if(arr[maxIndex] < arr[j]){
maxIndex = j;
}
}
if(i != maxIndex){
swap(arr[i],arr[maxIndex]);
}
}
}
int main()
{
int arr[] = {1,2,4,6,3};
int len = sizeof(arr)/sizeof(int);
printArray(arr,len);
mySort(arr,len);
printArray(arr,len);//64321
}
类模板成员函数创建时机
在运行时创建
类模板与继承
#include <iostream>
using namespace std;
template<class T>
class Base{
T obj1;
};
class Son1:public Base<int>{//必须要知道父类中T的类型才可以继承
};
template<class T1,class T2>
class Son2:public Base<T1>{
T2 obj2;
};
int main()
{
cout << "Hello World1";
return 0;
}
类模板成员函数类外实现
#include <iostream>
#include <string>
using namespace std;
template<class T1,class T2>
class Person{
public:
T1 name;
T2 age;
Person(T1 name,T2 age);
void showPerson();
};
template<class T1,class T2>
Person<T1,T2>::Person(T1 name,T2 age){
this->name = name;
this->age = age;
}
template<class T1,class T2>
void Person<T1,T2>::showPerson(){
cout << "姓名:" << name << ",年龄:" << age << endl;
}
int main()
{
Person<string,int> p("zh",22);
p.showPerson();
return 0;
}
类模板分文件编写
- 直接包含源文件
- 将.h和.cpp的内容写到一起,将后缀名改为.hpp
类模板与友元
#include <iostream>
#include <string>
using namespace std;
template<class T1,class T2>
class Person;
template<class T1,class T2>
void printPerson2(Person<T1,T2> p){
cout << "name:" << p.name << " age:" << p.age << endl;
}
template<class T1,class T2>
class Person{
//在类中定义全局函数
friend void printPerson1(Person p){
cout << "name:" << p.name << " age:" << p.age << endl;
}
//类外实现全局函数
friend void printPerson2<>(Person<T1,T2> p);
public:
Person(T1 name,T2 age){
this->name = name;
this->age = age;
}
private:
T1 name;
T2 age;
};
int main()
{
Person<string,int> p("zhang",22);
printPerson1(p);
printPerson2(p);
return 0;
}
自定义数组
#pragma
#include <iostream>
using namespace std;
template<class T>
class MyArray {
public:
T* array;
int len;
int capacity;
MyArray(int capacity) {
this->capacity = capacity;
this->array = new T[this->capacity];
this->len = 0;
}
MyArray(const MyArray& myArray) {
this->capacity = myArray.capacity;
this->array = new T[myArray.capacity];
this->len = myArray.len;
for (int i = 0; i < len; ++i) {
this->array[i] = myArray.array[i];
}
}
~MyArray() {
delete[] array;
}
MyArray& operator =(const MyArray& myArray) {
if (this->array != NULL){
delete[] this->array;
this->array = NULL;
}
this->len = myArray.len;
this->array = new T[len];
this->capacity = myArray.capacity;
for (int i = 0; i < len; ++i) {
this->array[i] = myArray.array[i];
}
return *this;
}
T& operator [](int i) {
return this->array[i];
}
void push(const T& t) {
if (len == capacity) {
return;
}
this->array[len] = t;
this-> len ++;
}
void pop() {
if (len == 0) {
return;
}
this->len --;
}
int getLength() {
return this->len;
}
int getCapacity() {
return this->capacity;
}
};
STL
在 C++ 中,STL(Standard Template Library)是一个非常重要的组成部分,它提供了大量的通用模板类和函数,用于处理常见的数据结构和算法。STL 是 C++ 标准库的一部分,并且被广泛用于各种 C++ 程序中。
STL 主要由以下几个组件组成:
容器(Containers):STL 提供了多种类型的容器,如向量(std::vector)、列表(std::list)、双端队列(std::deque)、集合(std::set)、映射(std::map)等。这些容器类模板用于存储和管理数据元素。 迭代器(Iterators):迭代器提供了一种访问容器中元素的方式,它们类似于指针,但更为通用。迭代器可以遍历容器中的所有元素,并允许我们读取或修改这些元素的值。 算法(Algorithms):STL 提供了大量用于操作容器中元素的算法,如排序(std::sort)、查找(std::find)、复制(std::copy)等。这些算法通常与容器和迭代器一起使用,以实现对容器中数据的复杂操作。 函数对象(Function Objects):函数对象(也称为仿函数或函数子)是 STL 中一个重要的概念。它们是可以像函数一样被调用的对象,通常用于作为算法的参数,以定义算法的行为。 适配器(Adapters):适配器用于修改容器或迭代器的行为,以适应不同的算法需求。例如,std::stack 和 std::queue 是基于其他容器(如 std::deque)的适配器,它们提供了栈和队列的接口。 分配器(Allocators):分配器用于管理容器中元素的内存分配和释放。虽然大多数程序员不需要直接使用分配器,但它们为 STL 提供了高度的灵活性和可定制性。 通过使用 STL,程序员可以更加高效地编写 C++ 代码,因为 STL 中的组件已经经过了优化和测试,并且与 C++ 标准库的其他部分紧密集成。此外,STL 的模板特性使得代码更加通用和可重用,减少了编写重复代码的需要。
vector
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
vector<int> v;
v.push_back(11);
v.push_back(15);
v.push_back(7);
for (size_t i = 0; i < v.size(); ++i) {
cout << v[i] << " ";
}
cout << endl; // 输出: 11 15 7
// 使用迭代器遍历vector
for (vector<int>::iterator it = v.begin(); it != v.end(); ++it) {
cout << *it << " ";
}
cout << endl; // 输出: 11 15 7
//排序
sort(v.begin(), v.end(), [](int a, int b) { return a > b; });
for (size_t i = 0; i < v.size(); ++i) {
cout << v[i] << " ";
}
cout << endl; // 输出: 7 11 15
return 0;
}
使用swap压缩空间
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
for (int i = 0; i < 17; ++i) {
v.push_back(i);
}
v.pop_back();
v.pop_back();
v.pop_back();
v.pop_back();
v.pop_back();
cout << "capacity: " << v.capacity() << endl; //32
//创建匿名对象,将匿名对象和原来的对象交换,达到压缩空间的目的
vector<int> (v).swap(v);
cout << "capacity: " << v.capacity() << endl; //12
return 0;
}
预分配空间
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> v;
int num = 0;
int* ptr = NULL;
for (int i = 0; i < 17; ++i) {
v.push_back(i);
if (ptr != &v[0]){
ptr = &v[0];
num++;
}
}
//查看扩容次数 6-1=5
cout << "num: " << num << endl;
vector<int> v1;
v1.reserve(20);//预先申请20容量,避免多次扩容消耗性能
int num1 = 0;
int* ptr1 = NULL;
for (int i = 0; i < 17; ++i) {
v1.push_back(i);
if (ptr1 != &v1[0]){
ptr1 = &v1[0];
num1++;
}
}
//查看扩容次数 1-1=0
cout << "num1: " << num1 << endl;
return 0;
}
deque
基础
#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;
//打印
void printDq(const deque<int>& d){
for (deque<int>::const_iterator it = d.begin();it != d.end();it++ ) {
cout << *it << " ";
}
cout << endl;
}
int main() {
deque<int> dq;
for (int i = 0; i < 5; ++i) {
dq.push_back(i);
}
printDq(dq);
//赋值
deque<int> d1 = dq;
printDq(d1);
//传入开始结束
deque<int> d2(dq.begin(),dq.end());
printDq(d2);
//10个100
deque<int> d3(10,100);
printDq(d3);
//构造函数赋值
deque<int> d4(d3);
printDq(d4);
//assign方式赋值
deque<int> d5;
d5.assign(d4.begin(),d4.end());
printDq(d5);
//10个10
deque<int> d6;
d6.assign(10,10);
printDq(d6);
cout << "长度:" << d6.size() << endl;
//重新设置长度
d6.resize(5);
printDq(d6);
//默认补0
d6.resize(10);
printDq(d6);
//指定补5
d6.resize(15,5);
printDq(d6);
//插入
d6.push_back(100);
d6.push_front(1);
printDq(d6);//1 10 10 10 10 10 0 0 0 0 0 5 5 5 5 5 100
//区间插入
d2.insert(d2.begin(),d1.begin(),d1.end());
printDq(d2);//0 1 2 3 4 0 1 2 3 4
//头删除
d3.pop_front();
printDq(d3);
//尾删除
d3.pop_back();
printDq(d3);
//指定删除
deque<int>::iterator it = d2.begin();
it ++;
d2.erase(it);
printDq(d2);//0 2 3 4 0 1 2 3 4
//清空,相当于clear
d2.erase(d2.begin(),d2.end());
printDq(d2);
//排序,默认从小到大
sort(d6.begin(),d6.end());
printDq(d6);
return 0;
}
案例
- 创建5名选手,放到vector中
- 遍历vector容器,取出每一个选手,进行10个打分放到deque中
- sort算法堆deque容器中分数排序,去掉最高分和最低分
- 计算每个选手deque中的平均分
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
#include <string>
#include <ctime>
using namespace std;
class Person{
public:
Person(string name){
this->name = name;
}
void setAvgScore(int score){
this->avgScore = score;
}
string getName(){
return this->name;
}
int getAvgScore(){
return this->avgScore;
}
private:
string name;
int avgScore;
};
int main() {
//随机种子
srand((unsigned int) time(NULL));
//创建5名选手
string names = "ABCDE";
vector<Person> persons;
for (int i = 0; i < 5; ++i) {
string name = "选手";
name += names[i];
Person p(name);
persons.push_back(p);
}
//给每个选手打分
for (int i=0;i<persons.size();i++) {
Person& person = persons[i];
deque<int> scores;
for (int j = 0; j < 10; ++j) {
int score = rand()%41 + 60;
scores.push_back(score);
}
//排序
sort(scores.begin(),scores.end());
//去掉最高分和最低分
scores.pop_back();
scores.pop_front();
//计算平均分
int sum = 0;
for (int j = 0; j < scores.size(); ++j) {
sum += scores[j];
}
int avg = sum/scores.size();
person.setAvgScore(avg);
}
//打印5名选手的分数
for (int i = 0; i < persons.size(); ++i) {
Person person = persons[i];
cout << "姓名:" <<person.getName() << " 得分:" << person.getAvgScore() << endl;
}
return 0;
}
栈
#include <iostream>
#include <stack>
using namespace std;
int main() {
stack<int> s;
s.push(1);
s.push(2);
s.push(3);
s.push(4);
s.push(5);
while (!s.empty()){
cout << "栈顶: " << s.top() << endl;
cout << "栈大小: " << s.size() << endl;
//出栈
s.pop();
}
return 0;
}
队列
#include <iostream>
#include <queue>
#include <string>
using namespace std;
class Person{
public:
Person(string name,int age){
this->name = name;
this->age = age;
}
string name;
int age;
void print(){
cout << "姓名: " << name << " 年龄: " << age << endl;
}
};
int main() {
queue<Person> q;
Person p1("唐僧",30);
Person p2("孙悟空",1000);
Person p3("猪八戒",900);
Person p4("沙僧",800);
q.push(p1);
q.push(p2);
q.push(p3);
q.push(p4);
while (!q.empty()){
q.front().print();
q.pop();
}
return 0;
}
list
构造函数
#include <iostream>
#include <list>
using namespace std;
void printList(list<int>& ls){
for (list<int>::iterator it = ls.begin();it != ls.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
printList( l1);
list<int> l2(l1.begin(),l1.end());
printList(l2);
list<int> l3(l2);
printList(l3);
list<int> l4(10,100);
printList(l4);
return 0;
}
赋值和交换
#include <iostream>
#include <list>
#include <algorithm>
#include <string>
using namespace std;
void printList(list<int>& ls){
for (list<int>::iterator it = ls.begin();it != ls.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
printList( l1);
//=赋值
list<int> l2 = l1;
printList(l2);
//assign 赋值
list<int> l3;
l3.assign(l1.begin(),l1.end());
printList(l3);
list<int> l4;
l4.assign(10,100);
printList(l4);
//交换
cout << "交换前" << endl;
printList(l1);
printList(l4);
l4.swap(l1);
cout << "交换后" << endl;
printList(l1);
printList(l4);
return 0;
}
指定大小
#include <iostream>
#include <list>
using namespace std;
void printList(list<int>& ls){
for (list<int>::iterator it = ls.begin();it != ls.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
if (l1.empty()){
cout << "为空" << endl;
}else{
cout << "不为空" << endl;
cout << "长度为:" << l1.size() << endl;
}
//重新指定大小
l1.resize(10);
printList(l1);
//缩小时,多余元素会被删除
l1.resize(2);
printList(l1);
return 0;
}
插入和删除
#include <iostream>
#include <list>
using namespace std;
void printList(list<int>& ls){
for (list<int>::iterator it = ls.begin();it != ls.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
//头插入
l1.push_front(10);
l1.push_front(20);
printList(l1);//20 10 1 2 3 4
//insert插入
list<int>::iterator it = l1.begin();
l1.insert(++it,1000);
printList(l1);//20 1000 10 1 2 3 4
//删除
it = l1.begin();
l1.erase(it);
printList(l1);//1000 10 1 2 3 4
//移除 删除所有满足条件的数据
l1.push_back(10000);
l1.push_back(10000);
l1.push_back(10000);
l1.push_back(10000);
l1.push_back(10000);
l1.remove(10000);
printList(l1); //1000 10 1 2 3 4
//清空
l1.clear();
printList(l1);
return 0;
}
数据存取
#include <iostream>
#include <list>
#include <algorithm>
#include <string>
using namespace std;
void printList(list<int>& ls){
for (list<int>::iterator it = ls.begin();it != ls.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
//list是链表,不支持随机范围,[]和at都不可用
cout << "第一个元素:" << l1.front() << endl;
cout << "最后一个元素:" << l1.back() << endl;
list<int>::iterator it = l1.begin();
it++;
it--;
//不支持it+1
return 0;
}
排序和反转
#include <iostream>
#include <list>
#include <string>
using namespace std;
void printList(list<int>& ls){
for (list<int>::iterator it = ls.begin();it != ls.end();it++) {
cout << *it << " ";
}
cout << endl;
}
bool compare(int v1,int v2){
return v1 > v2;
}
int main() {
list<int> l1;
l1.push_back(5);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
cout << "排序前" << endl;
printList(l1);
l1.sort();
cout << "排序后" << endl;
printList(l1);
//从大到校排序,需要自定义排序函数
l1.sort(compare);
cout << "从大到小排序后:" << endl;
printList(l1);
//反转
l1.reverse();
printList(l1);
return 0;
}
排序案例
- 将Person进行排序,对象属性为姓名、年龄、身高
- 排序规则,按照年龄升序,如果年龄相同安装身高降序
#include <iostream>
#include <list>
#include <string>
using namespace std;
class Person{
public:
Person(string name,int age,int height){
this->name = name;
this->age = age;
this->height = height;
}
string name;
int age;
int height;
};
void printList(list<Person>& ls){
for (list<Person>::iterator it = ls.begin();it != ls.end();it++) {
cout << " 姓名:" << it->name << " 年龄:" << it->age << " 身高:" << it->height << endl;
}
}
bool compare(Person& p1,Person& p2){
if (p1.age == p2.age){
return p1.height > p2.height;
} else{
return p1.age < p2.age;
}
}
int main() {
list<Person> ls;
Person p1("刘备",35,175);
Person p2("曹操",45,180);
Person p3("孙权",40,170);
Person p4("赵云",25,190);
Person p5("张飞",35,160);
Person p6("关羽",35,200);
ls.push_back(p1);
ls.push_back(p2);
ls.push_back(p3);
ls.push_back(p4);
ls.push_back(p5);
ls.push_back(p6);
cout << "排序前:" << endl;
printList(ls);
ls.sort(compare);
cout << "排序后:" << endl;
printList(ls);
return 0;
}
set
构造和赋值
#include <iostream>
#include <set>
#include <string>
using namespace std;
void printSet(set<int>& s){
for (set<int>::iterator it = s.begin();it != s.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
set<int> s;
s.insert(10);
s.insert(40);
s.insert(30);
s.insert(20);
s.insert(30);
printSet(s);//10 20 30 40
//拷贝构造
set<int> s2(s);
return 0;
}
容器大小和交换
#include <iostream>
#include <set>
#include <string>
using namespace std;
void printSet(set<int>& s){
for (set<int>::iterator it = s.begin();it != s.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
set<int> s;
s.insert(10);
s.insert(40);
s.insert(30);
s.insert(20);
s.insert(30);
if (s.empty()){
cout << "容器是空的" << endl;
}else{
cout << "大小:" << s.size() << endl;
}
set<int> s1;
s1.insert(100);
s1.insert(400);
cout << "交换前" << endl;
printSet(s);
printSet(s1);
s.swap(s1);
cout << "交换后" << endl;
printSet(s);
printSet(s1);
return 0;
}
插入和删除
#include <iostream>
#include <set>
#include <string>
using namespace std;
void printSet(set<int>& s){
for (set<int>::iterator it = s.begin();it != s.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
set<int> s;
s.insert(10);
s.insert(40);
s.insert(30);
s.insert(20);
s.insert(30);
//删除
s.erase(s.begin());
printSet(s);//20 30 40
s.erase(30);
printSet(s);//20 30 40
s.erase(s.begin(),s.end());
s.clear();
return 0;
}
查找和统计
#include <iostream>
#include <set>
#include <string>
using namespace std;
void printSet(set<int>& s){
for (set<int>::iterator it = s.begin();it != s.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
set<int> s;
s.insert(10);
s.insert(40);
s.insert(30);
s.insert(20);
s.insert(30);
//查找
set<int>::iterator it = s.find(30);
if (it != s.end()){
cout << "找到了" << endl;
}else{
cout << "没找到" << endl;
}
//统计
int num = s.count(30);
cout << num << endl;//1
multiset<int> ms;
ms.insert(1);
ms.insert(1);
ms.insert(1);
ms.insert(1);
int num1 = ms.count(1);
cout << num1 << endl;//4
return 0;
}
pair
#include <iostream>
#include <string>
using namespace std;
int main() {
//第一种方式
pair<string,int> p("zh",12);
cout << "姓名: " << p.first << " 年龄: " << p.second << endl;
//第二种方式
pair<string,int> p2 = make_pair("zh",13);
cout << "姓名: " << p2.first << " 年龄: " << p2.second << endl;
return 0;
}
指定排序规则
#include <iostream>
#include <set>
#include <string>
using namespace std;
class MyCompare{
public:
bool operator()(int v1,int v2) const{
return v1 > v2;
}
};
int main() {
set<int,MyCompare> s;
s.insert(10);
s.insert(40);
s.insert(30);
s.insert(20);
s.insert(30);
for (set<int,MyCompare>::iterator it = s.begin();it != s.end();it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
map
构造和赋值
#include <iostream>
#include <map>
#include <string>
using namespace std;
void printMap(map<int,int> &m){
for (map<int,int>::iterator it = m.begin();it != m.end();it++){
cout << "key=" << it->first << " value=" << it->second << endl;
}
}
int main() {
map<int,int> m;
m.insert(pair<int,int>(1,1));
m.insert(pair<int,int>(2,1));
printMap(m);
//拷贝构造
map<int,int> m2(m);
printMap(m2);
//赋值
map<int,int> m3;
m3 = m2;
printMap(m3);
return 0;
}
容器大小和交换
#include <iostream>
#include <map>
#include <string>
using namespace std;
void printMap(map<int,int> &m){
for (map<int,int>::iterator it = m.begin();it != m.end();it++){
cout << "key=" << it->first << " value=" << it->second << endl;
}
}
int main() {
map<int,int> m;
m.insert(pair<int,int>(1,1));
if (m.empty()){
cout << "空的map" << endl;
}else{
cout << m.size() << endl;
}
map<int,int> m1;
m1.insert(pair<int,int>(2,1));
cout << "交换前:" << endl;
printMap(m);
printMap(m1);
m.swap(m1);
cout << "交换后:" << endl;
printMap(m);
printMap(m1);
return 0;
}
插入和删除
#include <iostream>
#include <map>
#include <string>
using namespace std;
void printMap(map<int,int> &m){
for (map<int,int>::iterator it = m.begin();it != m.end();it++){
cout << "key=" << it->first << " value=" << it->second << endl;
}
}
int main() {
map<int,int> m;
//插入
m.insert(pair<int,int>(1,1));
m.insert(make_pair(2,1));
m.insert(map<int,int>::value_type (3,1));
m[4] = 4;
printMap(m);
//删除
m.erase(m.begin());
printMap(m);
m.erase(3);
printMap(m);
m.clear();
printMap(m);
return 0;
}
查找和统计
#include <iostream>
#include <map>
#include <string>
using namespace std;
void printMap(map<int,int> &m){
for (map<int,int>::iterator it = m.begin();it != m.end();it++){
cout << "key=" << it->first << " value=" << it->second << endl;
}
}
int main() {
map<int,int> m;
m.insert(pair<int,int>(1,1));
m.insert(pair<int,int>(2,1));
m.insert(pair<int,int>(3,1));
//查找
map<int,int>::iterator pos = m.find(3);
if (pos != m.end()){
cout << "key=" << pos->first << " value=" << pos->second << endl;
}else{
cout << "未找到元素" << endl;
}
//统计
int num = m.count(3);
cout << "num=" << num << endl;
return 0;
}
排序
#include <iostream>
#include <map>
#include <string>
using namespace std;
class MyCompare{
public:
bool operator()(int v1,int v2) const{
return v1 > v2;
}
};
void printMap(map<int,int,MyCompare> &m){
for (map<int,int>::iterator it = m.begin();it != m.end();it++){
cout << "key=" << it->first << " value=" << it->second << endl;
}
}
int main() {
map<int,int,MyCompare> m;
m.insert(pair<int,int>(1,1));
m.insert(pair<int,int>(2,1));
m.insert(pair<int,int>(3,1));
printMap(m);
return 0;
}
函数对象
- 函数对象在使用时,可以像普通函数那样调用,可以有参数,可以有返回值
- 函数对象超出普通函数的概念,函数对象可以有自己的状态
- 函数对象可以作为参数传递
#include <iostream>
#include <string>
using namespace std;
class MyAdd{
public:
int operator()(int v1,int v2) const{
return v1 + v2;
}
};
int main() {
MyAdd myAdd;
int num = myAdd(1,2);
cout << num << endl;
return 0;
}
谓词
- 返回bool类型的仿函数称为谓词
- 如果operator()接受一个参数,那么叫一元谓词
- 如果operator()接受两个个参数,那么叫二元谓词
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class GreaterFive{
public:
bool operator()(int v1) const{
return v1 > 5;
}
};
int main() {
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
}
vector<int>::iterator it = find_if(v.begin(),v.end(),GreaterFive());
if (it == v.end()){
cout << "未找到" << endl;
} else{
cout << *it << endl;
}
return 0;
}
内建仿函数
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
using namespace std;
void test1(){
negate<int> n;
cout << n(50) << endl;
plus<int> p;
cout << p(10,10) << endl;
}
void test2(){
vector<int> v;
v.push_back(2);
v.push_back(4);
v.push_back(3);
v.push_back(5);
v.push_back(1);
for (vector<int>::iterator it =v.begin();it != v.end();it++) {
cout << *it << " ";
}
cout << endl;
sort(v.begin(),v.end(),greater<int>());
for (vector<int>::iterator it =v.begin();it != v.end();it++) {
cout << *it << " ";
}
cout << endl;
}
void test3(){
vector<bool> v;
v.push_back(true);
v.push_back(false);
v.push_back(true);
v.push_back(false);
for (vector<bool>::iterator it =v.begin();it != v.end();it++) {
cout << *it << " ";
}
cout << endl;
vector<bool> v1;
v1.resize(v.size());
transform(v.begin(),v.end(),v1.begin(),logical_not<bool>());
for (vector<bool>::iterator it =v1.begin();it != v1.end();it++) {
cout << *it << " ";
}
cout << endl;
}
int main() {
//算术反函数
test1();
//关系仿函数
test2();
//逻辑仿函数
test3();
return 0;
}
算法
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Person{
public:
Person(string name, int age) {
this->name = name;
this->age = age;
}
bool operator==(const Person &p)
{
if (this->age == p.age)
{
return true;
}
else
{
return false;
}
}
string name;
int age;
};
void test1(vector<Person> v1){
//帅选出年龄大于25的第一个对象
vector<Person>::iterator it = find_if(v1.begin(),v1.end(),[](Person &p){
return p.age > 25;
});
if (it != v1.end()){
cout << "找到了" << endl;
cout << "姓名:" << it->name << " 年龄:" << it->age << endl;
}else{
cout << "未找到" << endl;
}
}
void test2(vector<Person> v1){
//相邻两个对象,第一个大于第二个的年龄
vector<Person>::iterator it = adjacent_find(v1.begin(),v1.end(),[](Person &p1,Person &p2){
return p1.age > p2.age;
});
if (it != v1.end()){
cout << "找到了" << endl;
cout << "姓名:" << it->name << " 年龄:" << it->age << endl;
}else{
cout << "未找到" << endl;
}
}
void test3(vector<int> v1){
sort(v1.begin(),v1.end(),less<int>());
//只能对排好序的容器进行查找
bool b = binary_search(v1.begin(),v1.end(),2);
if (b){
cout << "找到了" << endl;
}else{
cout << "未找到" << endl;
}
}
void test4(vector<Person> v1,Person &p){
//统计对象个数
int num = count(v1.begin(), v1.end(), p);
cout << num << endl;
}
void test5(vector<Person> v1){
int num = count_if(v1.begin(),v1.end(),[](Person &p){
return p.age > 25;
});
cout << num << endl;
}
void test6(vector<int> v1,vector<int> v2){
vector<int> result(v1.size() + v2.size());
std::merge(v1.begin(), v1.end(),v2.begin(),v2.end(),result.begin());
for_each(result.begin(),result.end(),[](int num){
cout << num << endl;
});
}
void test7(vector<Person> v1){
reverse(v1.begin(),v1.end());
for_each(v1.begin(),v1.end(),[&](Person p){
cout << "姓名:" << p.name << " 年龄:" << p.age << endl;
});
}
void test8(){
vector<int> source = {1, 2, 3, 4, 5};
vector<int> destination(source.size());
copy(source.begin(), source.end(), destination.begin());
// 输出复制后的容器
for (int num : destination) {
cout << num << " ";
}
cout << endl;
}
void test9(){
vector<int> source = {1, 2, 3, 4, 5};
replace(source.begin(),source.end(),2,200);
for (int num : source) {
cout << num << " ";
}
cout << endl;
}
void test10(){
vector<int> source = {1, 2, 3, 4, 5};
replace_if(source.begin(),source.end(),[](int num){
return num > 2;
},200);
for (int num : source) {
cout << num << " ";
}
cout << endl;
}
void test11(){
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {10, 20, 30, 40, 50};
swap(v1,v2);
for (int num : v1) {
cout << num << " ";
}
cout << endl;
for (int num : v2) {
cout << num << " ";
}
cout << endl;
}
void test12(){
vector<int> v1;
v1.resize(10);
fill(v1.begin(),v1.end(),100);
for (int num : v1) {
cout << num << " ";
}
cout << endl;
}
void test13(){
cout << "test13" << endl;
//两个源容器必须有序,且顺序一致
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {3,4,5,6,7};
vector<int> v3;
v3.resize(min(v1.size(),v2.size()));
vector<int>::iterator v3End = set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
for_each(v3.begin(),v3End,[](int num){
cout << num << endl;
});
}
void test14(){
cout << "test14" << endl;
//两个源容器必须有序,且顺序一致
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {3,4,5,6,7};
vector<int> v3;
v3.resize(min(v1.size(),v2.size()));
vector<int>::iterator v3End = set_difference(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
for_each(v3.begin(),v3End,[](int num){
cout << num << endl;
});//1,2
}
void test15(){
cout << "test15" << endl;
//两个源容器必须有序,且顺序一致
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2 = {3,4,5,6,7};
vector<int> v3;
v3.resize(min(v1.size(),v2.size()));
vector<int>::iterator v3End = set_union(v1.begin(),v1.end(),v2.begin(),v2.end(),v3.begin());
for_each(v3.begin(),v3End,[](int num){
cout << num << endl;
});
}
int main()
{
vector<Person> v1;
Person p1("刘备", 35);
Person p2("关羽",35);
Person p3("张飞", 35);
Person p4("赵云", 30);
Person p5("曹操", 40);
//将人员插入到容器
v1.push_back(p1);
v1.push_back(p2);
v1.push_back(p3);
v1.push_back(p4);
v1.push_back(p5);
for_each(v1.begin(),v1.end(),[](Person &p){
cout << "姓名:" << p.name << " 年龄:" << p.age << endl;
});
//find_if
test1(v1);
//adjacent_find
test2(v1);
//binary_search
test3({1,3,9,5,4,2});
//count
test4(v1,p1);
//count_if
test5(v1);
cout << "--------------" << endl;
//merge
test6({1,3,4},{2,5,7});
//reverse
test7(v1);
//copy
test8();
//replace
test9();
//replace_if
test10();
//swap
test11();
//fill
test12();
//交集
test13();
//差集
test14();
//并集
test15();
return 0;
}