Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
Home
  • 计算机网络
  • 操作系统
  • 数据结构与算法
  • 设计模式
  • JavaSE
  • JVM
  • JUC
  • Netty
  • CPP
  • QT
  • UE
  • Go
  • Gin
  • Gorm
  • HTML
  • CSS
  • JavaScript
  • vue2
  • TypeScript
  • vue3
  • react
  • Spring
  • SpringMVC
  • Mybatis
  • SpringBoot
  • SpringSecurity
  • SpringCloud
  • Mysql
  • Redis
  • 消息中间件
  • RPC
  • 分布式锁
  • 分布式事务
  • 个人博客
  • 弹幕视频平台
  • API网关
  • 售票系统
  • 消息推送平台
  • SaaS短链接系统
  • Linux
  • Docker
  • Git
GitHub (opens new window)
  • C++语法
    • 指针
    • 引用
    • 类和对象
      • 成员函数
      • 构造函数
      • 析构函数
      • 静态成员变量/函数
      • this指针
      • 常函数/对象
      • 友元
      • 重载
      • 继承
      • 多态
    • 模板
      • 函数模板
      • 类模板
    • STL容器
      • string
      • vector
      • deque
      • stack
      • queue
      • list
      • set/multiset
      • map/multimap
    • STL算法
      • 遍历
      • 查找
      • 排序
      • 拷贝替换
      • 算数
      • 集合
    • 文件操作
  • C++11实用特性
  • CPP
Nreal
2023-11-07
目录

C++语法

# 指针

常量指针:const int * p = &a;

指针指向可以修改,但是指针指向的值不可以修改;

指针常量:int * const p = &a;

指针指向不可以修改,指针指向的值可以修改;

数组指针:

数组名就是数组的首地址;

int arr[5] = {1,2,3,4,5};
int * p = arr;
cout<<"首元素: "<<*p<<endl;
p++;//让指针向后偏移4个字节
cout<<"第二个元素: "<<*p<<endl;
1
2
3
4
5

函数指针:

地址传递

void swap(int * p,int * q){
    int tmp = *p;
    *p = *q;
    *q = tmp;
}
int main(){
    int a=10;
    int b=20;
    swap(&a,&b);
}
1
2
3
4
5
6
7
8
9
10

冒泡排序案例:

#include<iostream>
using namespace std;

void bubbleSort(int* arr, int n) {
	for (int i = 0; i < n - 1; i++) {
		for (int j = 0; j < n - i - 1; j++) {
			if (arr[j] > arr[j + 1]) {
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

int main() {
	int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
	int n = sizeof(arr) / sizeof(arr[0]);
	bubbleSort(arr, n);
	for (int i = 0; i < n; i++) {
		cout << arr[i]<<" ";
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

结构体指针:

利用操作符->通过结构体指针访问结构体属性

#include<iostream>
using namespace std;

struct Student{
	string name;
	int age;
	int score;
};

int main() {
	Student st = { "张三",18,60 };
	Student * p = &st;
	cout << "姓名: " << p->name;
    cout << "年龄: " << st.age;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

常量结构体指针:const Student * s

不允许修改结构体里的值

# 引用

作用:给变量起别名

语法:数据类型 &别名 = 原名

引用必须初始化,不能更改只能赋值;

int a=10;
int b=20;
int &c = a;
c = b;//这是赋值
1
2
3
4

引用传递:

void swap(int& a, int& b) {
	int tmp = a;
	a = b;
	b = tmp;
}

int main() {
	int a = 10;
	int b = 20;
	swap(a, b);
	cout << "a=" << a << ",b=" << b;
}
1
2
3
4
5
6
7
8
9
10
11
12

引用做函数返回值:

不要返回局部变量的引用;

函数的返回值是引用,函数的调用可以作为左值;

引用的本质:指针常量

常量引用:修饰形参,防止误操作;

//编译器修改:
//int tmp = 10; const int & ref = tmp;
const int & ref = 10;//不加const错误,必须引用合法内存空间
1
2
3

函数重载问题:

void func(int &a){
}
void func(const int &a){
}

int main(){
    int a = 10;
    func(a);//调用无const;
    func(10);//调用有const;
}
1
2
3
4
5
6
7
8
9
10

# 类和对象

class与struct区别:struct默认权限是public,class默认private

# 成员函数

指针调用成员函数:

class Person{
public:
    void showPersonName(){
        cout<<"name= "<<name<<endl;//this->name
    }
    String name;
}
void test(){
    Person* p = NULL;
    p->showPersonName();
}
1
2
3
4
5
6
7
8
9
10
11

报错:因为name省略了this->,指针指向为空;

类外写成员函数:

class Person{
public:
    study();
};
Person::study();
1
2
3
4
5

# 构造函数

构造函数:类名(){}

class Person{   
public:
 Person(){}//无参构造
 //有参构造
 Person(int a){
     age = a;
 }
 //拷贝构造
 Person(const Person &p){
     age = p.age
 }
 int age;
};

//调用
void test(){
 //1.括号法
 Person p0;
 Person p1(10);
 Person p2(p1);
 //2.显示法
 Person p0;
 Person p1 = Person(10);//函数右侧为匿名对象,执行结束回收掉
 Person p2 = Person(p1);
 //3.隐式转换法
 Person p4 = 10;
 Person p5 = p4;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

拷贝构造函数调用时机:

  • 值传递方式给函数传参;
  • 值方式返回局部对象;

调用规则:

  • 如果手动定义了有参构造,编译器不会提供无参构造,但是会提供拷贝构造;
  • 如果定义拷贝构造,不会再提供其它构造函数;

初始化列表:

Person(int a,int b,int c):m_A(a),m_B(b),m_C(c){  
}
int m_A;
int m_B;
int m_C;

//调用
Person p(30,20,10);

1
2
3
4
5
6
7
8
9

# 析构函数

析构函数:~类名(){}

堆区开辟的数据释放

class Person{
public:
	Person(int age,int height){
     m_Age = age;
     m_Height = new int(height);
 }   
 ~Person(){
		if(m_Height!=NULL){
         delete m_Height;
         m_Height = NULL;
     }
 }
 int m_Age;
 int *m_Height;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

浅拷贝问题:只是将指针引用又指向堆区内存,堆区内存重复释放;

深拷贝:堆区重开一块内存

//自己实现拷贝函数,解决浅拷贝问题
Person(const Person &p){
 m_Age = p.m_Age;
 //m_Height = p.m_Height; 编译器默认这种
 //深拷贝操作
 m_Height = new int(*p.m_Height);
}
1
2
3
4
5
6
7

# 静态成员变量/函数

静态成员变量:

class Person{
public:
    static int m_A;//类内申明,类外初始化操作
};
int Person::m_A = 100;
1
2
3
4
5

两种访问:

  • 通过对象 Person p; p.m_A;
  • 通过类名 Person::m_A

静态成员函数:只能访问静态成员变量

# this指针

this指针:

  1. 参数与成员变量重名;
  2. 返回
Class Person{
public:
    Person(int age){
        this->age = age;
    }
    Person& PersonAddAge(Person &p){
        this->age += p.age;
        //返回对象本身
        return *this;
    }
    int age;
};

void test(){
    Person p1(10);
    Person p2(10);
    //链式编程思想
    p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 常函数/对象

常函数/对象:mutable

Class Person{
public:
    void showPerson() const{
        //this->m_A = 100; 报错,常量指针 值不可修改
        //this = NULL; 报错,指针常量 指向不可修改
        this->m_B = 100;
    }
    int m_A;
    mutable int m_B;//特殊变量,即使常函数,也可以修改这个值
};

void test(){
    Person p;
    p.showPerson();
}

void test2(){
    const Person p;
    p.m_B = 100;
    //p.m_A = 100;报错
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

this指针本质:指针常量

常函数相当于前面再加了个const :const Person * const this;

常对象只能调用常函数;

# 友元

友元:全局函数,友元类,成员函数

关键字friend,可以访问private成员;

成员函数访问私有属性案例:

#include<iostream>
using namespace std;

class Building;
class GoodGay {
public:
	GoodGay();
	void visit();
	Building* building;
};
class Building {
	//告诉编译器,GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员
	friend void GoodGay::visit();
public:
	Building();
public:
	string m_SittingRoom;
private:
	string m_BedRoom;
};
//类外实现成员函数
Building::Building() {
	m_SittingRoom = "客厅";
	m_BedRoom = "卧室";
}
GoodGay::GoodGay() {
	building = new Building;
}
void GoodGay::visit() {
	cout << building->m_SittingRoom<<endl;
	cout << building->m_BedRoom << endl;
}
void test() {
	GoodGay gg;
	gg.visit();
}
int main() {
	test();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

# 重载

运算符重载:

  • 加号

    #include<iostream>
    using namespace std;
    
    class Person {
    public:
    	//成员函数重载
    	//Person operator+(Person& p) {
    	//	Person tmp;
    	//	tmp.m_A = this->m_A + p.m_A;
    	//	tmp.m_B = this->m_B + p.m_B;
    	//	return tmp;
    	//}
    
    	int m_A;
    	int m_B;
    };
    //全局函数重载
    Person operator+(Person& p1, Person& p2) {
    	Person tmp;
    	tmp.m_A = p1.m_A + p2.m_A;
    	tmp.m_B = p1.m_B + p2.m_B;
    	return tmp;
    }
    void test() {
    	Person p1;
    	p1.m_A = 10;
    	p1.m_B = 10;
    	Person p2;
    	p2.m_A = 10;
    	p2.m_B = 10;
    	//成员函数重载本质调用
    	//Person p3 = p1.operator+(p2);
    	//全局函数重载本质调用
    	//Person p3 = operator+(p1, p2);
    	Person p3 = p1 + p2;
    	cout << p3.m_A << p3.m_B << endl;
    }
    
    int main() {
    	test();
    	return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
  • 左移

    只能全局函数重载

    ostream operator<<(ostream &cout,Person &p){
     cout<<"p.m_A="<<p.m_A<<"p.m_B="<<p.m_B;
     return cout;
    }
    void test(){
     Person p;
     p.m_A = 10;
     p.m_B = 10;
     cout<<p<<endl;
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  • 递增

    前置递增返回引用,后置递增返回值

    #include<iostream>;
    using namespace std;
    
    class MyInteger {
    	friend ostream& operator<<(ostream& out, MyInteger myint);
    public:
    	MyInteger() {
    		m_Num = 0;
    	}
    	//前置++,返回引用
    	MyInteger& operator++() {
    		m_Num++;
    		return *this;
    	}
    	//后置++
    	MyInteger operator++(int) {
    		//先返回,记录当前本身的值,本身+1,返回以前的值
    		MyInteger tmp = *this;
    		m_Num++;
    		return tmp;
    	}
    private:
    	int m_Num;
    };
    
    ostream& operator<<(ostream& out, MyInteger myint) {
    	out << myint.m_Num;
    	return out;
    }
    
    void test01() {//前置++
    	MyInteger myInt;
    	cout << ++myInt << endl;
    	cout << myInt << endl;
    }
    void test02() {//后置++
    	MyInteger myInt;
    	cout << myInt++ << endl;
    	cout << myInt << endl;
    }
    int main() {
    	test01();
    	test02();
    	return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
  • 赋值

    类中有属性指向堆区,赋值操作可能出现深浅拷贝问题;

    #include<iostream>;
    using namespace std;
    
    class Person {
    public:
    	Person(int age) {
    		m_Age = new int(age);//开辟到堆区
    	}
    	Person& operator=(Person& p) {
    		if (m_Age != NULL) {
    			delete m_Age;
    			m_Age = NULL;
    		}
    		//编译器提供的浅拷贝,内存重复释放
    		//m_Age = p.m_Age;
    		//用深拷贝解决
    		m_Age = new int(*p.m_Age);
    		return *this;
    	}
    	~Person() {
    		if (m_Age != NULL) {
    			delete m_Age;
    			m_Age = NULL;
    		}
    	}
    	int* m_Age;
    };
    void test() {
    	Person p1(18);
    	Person p2(20);
    	Person p3(30);
    	p3 = p2 = p1;
    	cout << *p1.m_Age << endl;
    	cout << *p2.m_Age << endl;
    	cout << *p3.m_Age << endl;
    }
    int main() {
    	test();
    	return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
  • 关系运算符

    class Person{
    public:
        Person(string name,int age){
            this.m_Name = name;
            this.m_Age = age;
        };
        bool operator==(Person & p){
            if(this->m_Name==p.m_Name && this->m_Age==p.m_Age){
                return true;
            }else{
                return false;
            }
        }
        string m_Name;
        int m_Age;
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  • 函数调用运算符(仿函数)

    class MyAdd{
    public:
        int operator()(int v1,int v2){
            return v1+v2;
        }
    };
    void test(){
        MyAdd add;
        //匿名对象调用
        cout<<MyAdd()(100,100)<<endl;
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

# 继承

语法:class A:public B

继承同名成员处理方式:

  • 访问子类同名成员,直接访问;
  • 访问父类同名成员,加作用域;
class Base{
public:
    Base(){
        m_A = 100;
    }
    void func(){}
    int m_A;
};

class Son : public Base{
public:
    Son(){
        m_A = 200;
    }
    void func(){}//子类会隐藏父类中同名成员函数
    int m_A;
};

void test(){
    Son s;
    cout<<s.m_A<<endl;//Son下的
    cout<<s.Base::m_A<<endl;//Base下的
    s.func();
    s.Base::func();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

继承同名静态成员处理方式:

通过对象、类名访问成员

class Base{
public:
    static void func(){}
    static int m_A;
};
int Base::m_A = 100;

class Son : public Base{
public:
    static void func(){}
    static int m_A;
};
int Son::m_A = 200;

//同名成员属性
void test(){
    //通过对象访问
    Son s;
    cout<<s.m_A<<endl;
    cout<<s.Base::m_A<<endl;
    
    //通过类名访问
    cout<<Son::m_A<<endl;
    cout<<Son::Base::m_A<<endl;
}

//同名成员函数
void test(){
    Son s;
    s.func();
    s.Base::func();
    
    Son::func():
    Son::Base::func();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 多态

静态多态:函数重载,运算符重载...复用函数名,编译阶段确定函数地址;

动态多态:派生类和虚函数实现运行时多态,运行阶段确定函数地址;

class Animal{
public:
    //virtual:虚函数,编译期就不能确定函数调用
    virtual void speek(){}
};

class Cat : public Animal{
public:
    void speek(){}
};

class Dog : public Animal{
public:
    void speek(){}
};

// 父类引用指向子类实例
void DoSpeek(Animal & animal){
    animal.speek();
}

void test(){
    Cat cat;
    DoSpeek(cat);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

纯虚函数:virtual 返回类型 函数名 (参数列表) = 0;

类中有纯虚函数,这个类成为抽象类

class Base{
public:
    //子类中必须重写父类中的虚函数
    virtual void func() = 0;
};

class Son : public Base{
public:
    virtual void func(){}
};

void test(){
    Base * base = NULL;
    base = new Son;
    base->func();
    delete base;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

虚析构与纯虚析构:

多态中,如果子类中有属性开辟到堆区,父类指针在释放时无法调用到子类的析构代码;

有纯虚构函数,此类为抽象类

虚析构:virtual ~类名(){}

纯虚析构:virtual ~类名()=0;

类名::~类名(){}

class Animal{
public:
    Animal(){}
    virtual void Speek()=0;
    virtual ~Animal()=0;
};
//纯析构函数调用
Animal::~Animal(){}

class Cat : public Animal{
public:
    Cat(String name){
        m_Name = new string(name);
    }
    virtual void Speek(){}
    ~Cat(){
        if(this->m_Name!=NULL){
            delete m_Name;
            m_Name = NULL;
        }
    }
    string * m_Name;
};

void test(){
    Animal *animal = new Cat("Tom");
    animal->Speek();
    //通过父类指针去释放导致子类对象清理不干净,内存泄露
    //给基类一个虚析构函数
    delete animal;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

# 模板

# 函数模板

语法:template<typename T>

typename 可以用class代替

自动类型推导/显示指定类型:

func<T>();
func();
1
2

选择排序案例:

#include<iostream>;
using namespace std;

template<typename T>
void mySwap(T& a, T& b) {
	T tmp = a;
	a = b;
	b = tmp;
}

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) {
			mySwap(arr[max], arr[i]);
		}
	}
}

template<typename T>
void printArray(T arr[], int len) {
	for (int i = 0; i < len; i++) {
		cout << arr[i] << " ";
	}
	cout << endl;
}

void test() {
	char charArr[] = "bsfaserlil";
	int num = sizeof(charArr) / sizeof(char);
	mySort(charArr, num);
	printArray(charArr, num);
}

int main() {
	test();
	return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

与普通函数区别:普通函数可以发生自动类型转换,模板函数需要<>中指定类型才能自动类型转换;

调用规则:

  1. 如果函数模板与普通函数都可以实现,优先普通函数;
  2. 通过空模板参数列表强制调用函数模板;
  3. 函数模板也能重载;
  4. 如果函数模板能更好匹配,优先调用函数模板;
void myPrint(int a,int b){}

template<typename T>
void myPrint(T a,T b){}

template<typename T>
void myPrint(T a,T b,T c){}

void test(){
    int a = 10;
    int b = 20;
    //1.如果函数模板与普通函数都可以实现,优先普通函数;
    myPrint(a,b);
    
    //2.通过空模板参数列表强制调用函数模板;
    myPrint<>(a,b);
    
    //3.函数模板重载
    int c = 30;
    myPrint(a,b,c);
    
    //4.如果函数模板能更好匹配,优先调用函数模板;
    char c1 = 'a';
    char c2 = 'b';
    myPrint(c1,c2);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

模板局限性:如果T是引用类型,无法正常运行,可以为特定类型提供具体化模板;

class Person {
public:
	Person(string name, int age) {
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};

//普通函数模板
template<class T>
bool myCompare(T& a, T& b) {
	if (a == b)
		return true;
	else
		return false;
}

//具体化模板
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 test() {
	Person p1("Tom", 10);
	Person p2("Tom", 10);
	bool ret = myCompare(p1, p2);
	if (ret)
		cout << "p1==p2" << endl;
	else
		cout << "p1!=p2" << endl;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

# 类模板

类模板没有自动类型推导,可以有默认参数

template<class NameType,class AgeType=int>
class Person{
public:
	Person(NameType name,AgeType age){
		this->m_Name = name;
		this->m_Age = age;
	}
	NameType m_Name;
	AgeType m_Age;
}
void test(){
	Person<string>P1("孙悟空",100);
}
1
2
3
4
5
6
7
8
9
10
11
12
13

创建时机:

  • 普通类成员函数一开始就创建;
  • 类模板中成员函数调用才创建;

类模板对象做函数参数:

  1. 指定传入类型,显示对象的数据类型;
  2. 参数模板化,将对象中的参数变为模板进行传递;
  3. 整个类模板化,将这个对象模板化进行传递;
template<class NameType,class AgeType=int>
class Person {
public:
	Person(NameType name,AgeType age) {
		this->name = name;
		this->age = age;
	}
	void show() {
		cout << this->name << this->age << endl;
	}
	NameType name;
	AgeType age;
};

//1.指定传入类型,常用
void print(Person<string, int>& p) {
	p.show();
}
void test1() {
	Person<string>p("孙悟空", 100);
	print(p);
}

//2.参数模板化
template<class T1,class T2>
void print2(Person<T1, T2>& p) {
	p.show();
	cout << "T1的类型为:" << typeid(T1).name() << endl;
}
void test2() {
	Person<string>p("猪八戒",90);
	print2(p);
}

//3.整个类模板化
template<class T>
void print3(T& p) {
	cout << "T的类型为:" << typeid(T).name() << endl;
	p.show();
}
void test3() {
	Person<string>p("唐僧", 30);
	print3(p);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

类模板继承:

子类继承父类模板,声明时,指定父类中T类型;

template<class T>
class Base {
	T m;
};
//必须指明类型,编译期需要给子类分配内存
class Son:public Base<int>{};

void test() {
	Son s;
}

//类模板继承模板,T2指定父类中T类型
template<class T1,class T2>
class GrandSon :public Base<T2> {
public:
	GrandSon() {
		cout << typeid(T1).name() << endl;
		cout << typeid(T2).name() << endl;
	}
};

void test2() {
	GrandSon<int, char> grandSon;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

类模板成员函数类外实现:

template<class T1,class T2>
class Person {
public:
	Person(T1 name, T2 age);
	void show();
	T1 name;
	T2 age;
};

//构造函数类外实现
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>::show() {
	cout << this->name << this->age << endl;
}

void test() {
	Person<string, int>p("Tom", 20);
	p.show();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

类模板分文件编写:

  • 方式1:包含.cpp源文件

  • 方式2:.hpp文件

    头文件为.hpp:

    #pragma once
    #include<iostream>
    using namespace std;
    
    template<class T1,class T2>
    class Person {
    public:
    	Person(T1 name, T2 age);
    	void show();
    	T1 name;
    	T2 age;
    };
    
    //构造函数类外实现
    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>::show() {
    	cout << this->name << this->age << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25

    .cpp文件:

    #include<iostream>
    using namespace std;
    #include "person.hpp"
    
    void test() {
    	Person<string, int>p("Tom", 10);
    	p.show();
    }
    int main() {
    	test();
    	return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

类模板友元:

建议类内实现

#include<iostream>
using namespace std;

//类外实现,先做函数模板声明
template<class T1, class T2> class Person;

//也可以先写函数声明,放到类后实现
template<class T1,class T2>
void printPerson2(Person<T1, T2>& p) {
	cout << "类外实现:" << p.name << p.age << endl;
}

template<class T1,class T2>
class Person {
	//1.全局函数配合友元 类内实现
	friend void printPerson(Person<T1, T2>& p) {
		cout << "类内实现:" << p.name << p.age << endl;
	}
	//2.全局函数配合友元 类外实现
	//加空模板的参数列表,类外实现需要让编译器提前知道这个函数存在
	friend void printPerson2<>(Person<T1, T2>& p);

public:
	Person(T1 name, T2 age) {
		this->name = name;
		this->age = age;
	}
private:
	T1 name;
	T2 age;
};

void test() {
	Person<string, int>p("Tom", 20);
	printPerson(p);
	printPerson2(p);
}

int main() {
	test();
	return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# STL容器

# string

  1. 构造

    string s1;//空字符串,无参构造
    
    const char* str = "hello";
    string s2(str);//string(const char* s)
    
    string s3(s2);//拷贝构造string(const string& str);
    
    string s4(10, 'a');//n个字符初始化
    
    1
    2
    3
    4
    5
    6
    7
    8
  2. 拼接

    string str1 = "我";
    str1 += "爱";
    str1.append("LOL");
    
    string str2 = ".......";
    str1.append(str2, 0, 1);//从下标0截取1字符
    
    1
    2
    3
    4
    5
    6
  3. 查找替换

    string str1 = "abcdefg";
    int pos = str1.find("gf");
    if (pos == -1) {
    	cout << "未找到" << endl;
    }
    pos = str1.rfind("fg");
    cout << pos << endl;
    
    str1.replace(1, 3, "1111");
    cout << str1 << endl;//a1111efg
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
  4. 字符串比较

    string s1 = "abc";
    string s2 = "bca";
    int ret = s1.compare(s2);
    cout << ret << endl;//-1
    
    1
    2
    3
    4
  5. 存取

    string str = "hello world";
    for (int i = 0; i < str.size(); i++) {
    	cout << str[i] << " ";
    }
    cout << endl;
    for (int i = 0; i < str.size(); i++) {
    	cout << str.at(i) << " ";
    }
    cout << endl;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
  6. 插入擦除

    string str = "hello";
    str.insert(1, "111");//h111ello
    cout << str << endl;
    str.erase(1, 3);//hello
    cout << str << endl;
    
    
    1
    2
    3
    4
    5
    6
  7. 子串

    string str = "hello";
    string subStr = str.substr(1, 3);
    string email = "hello@sina.com";
    int pos = email.find("@");
    string username = email.substr(0, pos);
    cout << subStr << username << endl;//ellhello
    
    1
    2
    3
    4
    5
    6

# vector

单端数组,可以动态扩展

  1. 构造遍历

    void printVector(vector<int>& v) {
    	for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    
    void test() {
    	vector<int> v1;//无参构造
    	for (int i = 0; i < 10; i++) {
    		v1.push_back(i);
    	}
    	printVector(v1);
    
    	vector<int> v2(v1.begin(),v1.end());//拷贝
    	printVector(v2);
    
    	vector<int> v3(3, 100);//n个ele拷贝给自己
    	printVector(v3);
    
    	vector<int> v4(v3);
    	printVector(v4);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
  2. 容量大小

    • empty():是否为空
    • capacity():容量,大于size
    • size():个数
    • resize(int num);resize(int num, elem):容器扩容后,默认值或elem填充;
  3. 插入删除

    vector<int> v;
    //尾插
    v.push_back(10);
    v.push_back(20);
    //尾删
    v.pop_back();
    printVector(v);
    //插入
    v.insert(v.begin(), 100);//100 10
    printVector(v);
    v.insert(v.begin(), 2, 8);//8 8 100 10
    printVector(v);
    //删除
    v.erase(v.begin());
    printVector(v);
    //清空
    v.erase(v.begin(), v.end());
    v.clear();
    printVector(v);
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
  4. 存取

    vector<int>v;
    for (int i = 0; i < 10; i++) {
    	v.push_back(i);
    }
    for (int i = 0; i < v.size(); i++) {
    	cout << v[i] << " ";
    	cout << v.at(i) << " ";
    }
    cout << endl;
    cout << v.front() << endl;
    cout << v.back() << endl;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  5. 互换容器

    vector<int>v1;
    for (int i = 0; i < 10; i++) {
    	v1.push_back(i);
    
    }
    vector<int>v2;
    for (int i = 10; i > 0; i--) {
    	v2.push_back(i);
    }
    v1.swap(v2);
    printVector(v1);
    printVector(v2);
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    收缩内存

    vector<int> v;
    for (int i = 0; i < 100000; i++) {
    	v.push_back(i);
    }
    //138255
    //100000
    cout << v.capacity() << endl;
    cout << v.size() << endl;
    
    v.resize(3);
    //138255
    //3
    cout << v.capacity() << endl;
    cout << v.size() << endl;
    
    //收缩内存
    vector<int>(v).swap(v);//匿名对象
    //3,3
    cout << v.capacity() << endl;
    cout << v.size() << endl;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
  6. 预留空间

    reserve(int len):预留len个元素长度,不初始化,不可访问;

# deque

双端数组;

  1. 插入删除

    push_back(ele);

    push_front(ele);

    pop_back();

    pop_front();

    insert(pos,ele);返回新数据位置

    insert(pos,n,ele);pos位置插入n个ele,无返回值

    insert(pos,begin,end);

    clear

    erase(begin,end);返回下一个数据的位置

    erase(pos);删除pos位置数据,返回下一个数据位置

  2. 排序

    #include<iostream>
    using namespace std;
    #include<deque>
    #include<algorithm>
    
    void printDeque(const deque<int>& d){
    	for (deque<int>::const_iterator it = d.begin(); it != d.end(); it++) {
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    
    void test() {
    	deque<int> d;
    	d.push_back(10);
    	d.push_front(20);
    	sort(d.begin(), d.end());
    	printDeque(d);
    }
    
    int main() {
    	test();
    	return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

# stack

  1. 存取

    push(ele)

    pop()

    top()返回栈顶元素

  2. empty()

    size()

# queue

  1. 存取

    push(ele)

    pop()

    back()返回最后一个元素

    front()返回第一个元素

# list

链表

  1. 插入删除

    void printList(const list<int>& l) {
    	for (list<int>::const_iterator it = l.begin(); it != l.end(); it++) {
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    
    void test() {
    	list<int> l;
    	l.push_back(10);
    	l.push_back(10);
    	l.push_front(100);
    	l.push_front(100);
    	
    	l.pop_back();
    	l.pop_front();
    
    	//插入
    	list<int>::iterator it = l.begin();
    	l.insert(++it, 8);
    	printList(l);//100 8 10
    
    	//删除
    	it = l.begin();
    	l.erase(++it);
    	printList(l);//100 10
    
    	l.push_back(1000);
    	l.push_back(1000);
    	l.push_back(1000);
    	l.remove(1000);
    	printList(l);
    	l.clear();
    	printList(l);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
  2. 存取

    front()

    back()

  3. 反转排序

    bool myCompare(int v1, int v2) {
    	return v1 > v2;
    }
    
    void test() {
    	list<int> l;
    	l.push_back(20);
    	l.push_back(30);
    	l.push_back(3);
    	l.push_back(6);
    
    	l.reverse();
    	printList(l);
    
    	l.sort();
    	printList(l);
    
    	l.sort(myCompare);
    	printList(l);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20

# set/multiset

所有元素自动排序,multiset允许有重复元素

  1. 插入删除

    #include<iostream>
    using namespace std;
    #include<set>
    
    void printSet(set<int>& s) {
    	for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    
    void test() {
    	set<int> s;
    	s.insert(10);
    	s.insert(0);
    	s.insert(20);
    	s.insert(30);
    	printSet(s);
    
    	s.erase(s.begin());
    	printSet(s);
    
    	s.erase(0);
    	printSet(s);
    
    	s.clear();
    	printSet(s);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
  2. 查找统计

    find(key):找到返回迭代器,找不到返回set.end();

    count(key):统计元素个数;

    void test() {
    	set<int> s;
    	s.insert(10);
    	s.insert(0);
    	s.insert(30);
    	s.insert(20);
    	set<int>::iterator pos = s.find(30);
    	if (pos != s.end()) {
    		cout << "找到了" << *pos << endl;
    	}
    	else {
    		cout << "未找到" << endl;
    	}
    	//统计
    	int num = s.count(30);
    	cout << num << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
  3. 排序

    仿函数

    class MyCompare {
    public:
    	//从大到小排序
    	bool operator()(int v1, int v2) const {
    		return v1 > v2;
    	}
    };
    
    void test() {
    	set<int,MyCompare> s;
    	s.insert(10);
    	s.insert(80);
    	s.insert(0);
    	s.insert(30);
    	for (set<int, MyCompare>::iterator it = s.begin(); it != s.end(); it++) {
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    
    int main() {
    	test();
    	return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class Person {
    public:
    	Person(string name, int age) {
    		this->name = name;
    		this->age = age;
    	}
    	string name;
    	int age;
    };
    class comparePerson {
    public:
    	bool operator()(const Person& p1, const Person& p2) const {
    		return p1.age > p2.age;
    	}
    };
    
    void test() {
    	set<Person, comparePerson> s;
    	Person p1("zhangsan", 39);
    	Person p2("lisi", 29);
    	Person p3("wangwu", 49);
    	s.insert(p1);
    	s.insert(p2);
    	s.insert(p3);
    	for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++) {
    		cout << it->name << it->age << endl;
    	}
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

# map/multimap

  1. 对组

    void test() {
    	pair<string, int>p(string("zhangsan"), 20);
    	cout << p.first << p.second << endl;
    }
    
    
    1
    2
    3
    4
    5
  2. 插入删除

    #include<map>
    
    void printMap(map<int,int>& m){
    	for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
    		cout << it->first << " " << it->second << endl;
    	}
    	cout << endl;
    }
    
    void test() {
    	map<int, int>m;
    	m.insert(pair<int, int>(1, 10));
    	m.insert(make_pair(2, 20));
    	m.insert(map<int, int>::value_type(3, 30));
    	m[4] = 40;
    	printMap(m);
    
    	//删除
    	m.erase(m.begin());
    	printMap(m);
    
    	//清空
    	m.erase(m.begin(), m.end());
    	m.clear();
    	printMap(m);
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
  3. 查找统计

    void test() {
    	map<int, int> m;
    	m.insert(pair<int, int>(1, 10));
    	m.insert(pair<int, int>(2, 20));
    	m.insert(pair<int, int>(3, 30));
    	//查找
    	map<int, int>::iterator pos = m.find(3);
    	if (pos != m.end()) {
    		cout << (*pos).first << " " << (*pos).second << endl;
    	}
    	else {
    		cout << "未找到" << endl;
    	}
    	int num = m.count(3);
    	cout << num << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
  4. 排序

    class MyCompare {
    public:
    	bool operator()(int v1, int v2) const {
    		return v1 > v2;
    	}
    };
    
    void test() {
    	map<int, int, MyCompare> m;
    	m.insert(make_pair(1, 10));
    	m.insert(make_pair(2, 20));
    	m.insert(make_pair(3, 30));
    	for (map<int, int, MyCompare>::iterator it = m.begin(); it != m.end(); it++) {
    		cout << it->first << " " << it->second << endl;
    	}
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17

# STL算法

# 遍历

  1. for_each

    #include<algorithm>
    #include<vector>
    
    class MyPrint {
    public:
    	void operator()(int val) {
    		cout << val << " ";
    	}
    };
    
    void MyPrint2(int val) {
    	cout << val << " ";
    }
    
    void test() {
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    	for_each(v.begin(), v.end(), MyPrint());
    	cout << endl;
    	for_each(v.begin(), v.end(), MyPrint2);
    	cout << endl;
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
  2. transform

    #include<algorithm>
    #include<vector>
    
    class Transform {
    public:
    	int operator()(int val) {
    		return val;
    	}
    };
    class MyPrint {
    public:
    	void operator()(int val) {
    		cout << val << " ";
    	}
    };
    
    void test() {
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    	vector<int> target;
    	target.resize(v.size());
    
    	transform(v.begin(), v.end(), target.begin(), Transform());
    	for_each(target.begin(), target.end(), MyPrint());
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28

# 查找

  1. find(iterator begin,iterator end,val);

  2. find_if

    返回第一个满足条件的

    #include<vector>
    #include<algorithm>
    
    class thanFive {
    public:
    	bool operator()(int val) {
    		return val > 5;
    	}
    };
    
    void test1() {
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    	vector<int>::iterator it = find_if(v.begin(), v.end(), thanFive());
    	if (it == v.end()) {
    		cout << "未找到" << endl;
    	}
    	else {
    		cout << *it << endl;
    	}
    }
    
    //自定义数据类型
    class Person {
    public:
    	Person(string name, int age) {
    		this->name = name;
    		this->age = age;
    	}
    	string name;
    	int age;
    };
    class than20 {
    public:
    	bool operator()(Person& p) {
    		return p.age > 20;
    	}
    };
    
    void test2() {
    	vector<Person> v;
    	Person p1("a", 32);
    	Person p2("aa", 2);
    	Person p3("aaa", 322);
    
    	v.push_back(p1);
    	v.push_back(p2);
    	v.push_back(p3);
    
    	vector<Person>::iterator it = find_if(v.begin(), v.end(), than20());
    	if (it == v.end()) {
    		cout << "未找到" << endl;
    	}
    	else {
    		cout << it->name << it->age << endl;
    	}
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
  3. adjacent_find(iterator begin,iterator end);

    返回相邻相同元素的第一个位置的迭代器;

  4. bool binary_search(iterator begin,iterator end,val)

    有序序列

  5. count(iterator begin,iterator end,val);

  6. count_if

    #include<vector>
    #include<algorithm>
    
    class than4 {
    public:
    	bool operator()(int val) {
    		return val >= 4;
    	}
    };
    void test1() {
    	vector<int>v;
    	v.push_back(1);
    	v.push_back(4);
    	v.push_back(5);
    	v.push_back(7);
    	int num = count_if(v.begin(), v.end(), than4());
    	cout << num << endl;
    }
    
    class Person {
    public:
    	Person(string name, int age) {
    		this->name = name;
    		this->age = age;
    	}
    	string name;
    	int age;
    };
    class than35 {
    public:
    	bool operator()(const Person& p) {
    		return p.age > 35;
    	}
    };
    void test2() {
    	vector<Person> v;
    	Person p1("a", 36);
    	Person p2("aa", 36);
    	v.push_back(p1);
    	v.push_back(p2);
    	int num = count_if(v.begin(), v.end(), than35());
    	cout << num << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43

# 排序

  1. sort

    #include<algorithm>
    #include<vector>
    
    void MyPrint(int val) {
    	cout << val << " ";
    }
    void test() {
    	vector<int> v;
    	v.push_back(10);
    	v.push_back(20);
    	v.push_back(5);
    	v.push_back(3);
    	sort(v.begin(), v.end());
    	for_each(v.begin(), v.end(), MyPrint);
    	cout << endl;
    
    	//从大到小
    	sort(v.begin(), v.end(), greater<int>());
    	for_each(v.begin(), v.end(), MyPrint);
    	cout << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
  2. random_shuffle

    class MyPrint {
    public:
    	void operator()(int val) {
    		cout << val << " ";
    	}
    };
    
    void test() {
    	vector<int> v;
    	for (int i = 0; i < 10; i++) {
    		v.push_back(i);
    	}
    	for_each(v.begin(), v.end(),MyPrint());
    	cout << endl;
    
    	random_shuffle(v.begin(), v.end());
    	for_each(v.begin(), v.end(), MyPrint());
    	cout << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
  3. merge

    class MyPrint {
    public:
    	void operator()(int val) {
    		cout << val << " ";
    	}
    };
    
    void test() {
    	vector<int> v1;
    	vector<int> v2;
    	for (int i = 0; i < 10; i++) {
    		v1.push_back(i);
    		v2.push_back(i + 1);
    	}
    	vector<int> target;
    	target.resize(v1.size() + v2.size());
    	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin());
    	for_each(target.begin(), target.end(), MyPrint());
    	cout << endl;
    }
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
  4. reverse

    void test() {
    	vector<int> v;
    	v.push_back(10);
    	v.push_back(40);
    	v.push_back(20);
    	v.push_back(30);
    	for_each(v.begin(), v.end(), MyPrint());
    	cout << endl;
    
    	reverse(v.begin(), v.end());
    	for_each(v.begin(), v.end(), MyPrint());
    	cout << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

# 拷贝替换

  1. copy(iterator begin,iterator end,iterator dest)

  2. replace(iterator begin,iterator end,oldval,newval);

  3. replace_if

    class MyPrint {
    public:
    	void operator()(int val) {
    		cout << val << " ";
    	}
    };
    
    class than30 {
    public:
    	bool operator()(int val) {
    		return val > 30;
    	}
    };
    
    void test() {
    	vector<int> v;
    	v.push_back(10);
    	v.push_back(40);
    	v.push_back(20);
    	v.push_back(30);
    	replace_if(v.begin(), v.end(), than30(), 88);
    	for_each(v.begin(), v.end(), MyPrint());
    	cout << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
  4. swap(container c1,container c2)

    类型需要相同

# 算数

  1. accumulate(iterator begin,iterator end,originalValue);
  2. fill(iterator begin,iterator end,val);

# 集合

  1. set_intersection

    交集;

    两个集合必须有序

    void test() {
    	vector<int> v1;
    	vector<int> v2;
    	for (int i = 0; i < 10; i++) {
    		v1.push_back(i);
    		v2.push_back(i + 5);
    	}
    	vector<int> target;
    	target.resize(min(v1.size(), v2.size()));
    
    	//返回目标容器最后一个元素迭代器地址
    	vector<int>::iterator itEnd = set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin());
    
    	for_each(target.begin(), itEnd, MyPrint());
    	cout << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
  2. set_union

    void test() {
    	vector<int> v1;
    	vector<int> v2;
    	for (int i = 0; i < 10; i++) {
    		v1.push_back(i);
    		v2.push_back(i + 5);
    	}
    	vector<int> target;
    	target.resize(v1.size()+ v2.size());
    
    	//返回目标容器最后一个元素迭代器地址
    	vector<int>::iterator itEnd = set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), target.begin());
    
    	for_each(target.begin(), itEnd, MyPrint());
    	cout << endl;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
  3. set_difference

# 文件操作

C++11实用特性

C++11实用特性→

Theme by Vdoing | Copyright © 2021-2024
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式