1.c和c++的区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream> // c++的包
#include "Student.h"
using namespace std; // 命名的空间,java中的类部内
/*
// 1. c++ 代码中可以混编 c 代码,c++ 里面写 c 代码,也可以调用
// 2. c++ 面向对象(Java),c 面向过程
// 3. 很多的开源框架大部分都是 c++ 写的 (大部分基于 c++ )
void main(){
// printf("Hello World");// c 的打印
// c++ 打印 opencv << 操作符重载
std::cout << "Hello World!" << std::endl;
getchar();
}

2.常量

1
2
3
4
5
6
7
8
9
void main(){
const int number = 10;
// number = 20;
// int* numberP = &number;// 不能通过地址去修改值,但是某些编译器上面能通过,但是也不能修改值
// c 是能够修改的,在 c 中可以说是一个伪命题
// *numberP = 20;
// printf("%d", number);
getchar();
}

3.引用和常量引用

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
// 引用
void swap(int &number1, int &number2){
cout << "swap number1的地址" << &number1 << endl;
int temp = 0;
temp = number1;
number1 = number2;
number2 = temp;
}
void main(){
int number1 = 10;
int number2 = 20;
// 引用: 四驱模型值的拷贝,引用其实是地址赋值 ,可以看成同一块内存的另外一个变量
cout << "main number1的地址" << &number1 << endl;
swap(number1,number2);
cout << "number1 = " << number1 << " , number2 = " << number2 << endl;
getchar();
}
//------------------------------------------------------------------------------------------------
//常量引用
typedef struct
{
char name[20];
int age;
}Student;

void insertStu(const Student &stu){// stu 不想改 常量引用
// 可以修改 stu 的值
// strcpy(stu.name,"Jack");
// 就变成了只读
cout << stu.name << "," << stu.age << endl;
}
void main(){
Student stu = {"Darren",20};
insertStu(stu);
getchar();
}

4.函数重载和默认参数

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.函数重载和默认参数
int add(int number1, int number2 = 200, bool cache= 0){ // number2 = 200 默认的参数 kotlin 很像
return number1 + number2;
}
// 错误 1 error C2084: 函数“int add(int,int)”已有主体 c 不允许函数的重载
int add(int number1, int number2, int number3){
return number1 + number2 + number3;
}

void main(){
int number1 = 100;
int number2 = 200;
int sum = add(number1,200);//报错

// bool 类型 0是true 和 !0 都是false
bool cache = -100;
if (cache){
cout << "true" << endl;
}else
{
cout << "false" << endl;
}
// printf("sum = %d", sum);

getchar();
}

5.类的初探

1
2
3
1.class 定义类,跟java 几乎类似
2.真正的开发过程中我们的 pp 或者 文件,最终 d 或者 库供调用者使用,所以为了确保类能正常被调用,我们般需要定义.h 头文件
3实现方法的使用要用命名空间 xxx类名::xxx方法

Student.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Student{ // 结构体类似
private: // 私有,包装,影响下面所有的属性
char* name;
int age;
public:
void setAge(int age);

void setName(char* name);
// private: // 影响到下面的所有方法

int getAge();

char* getName();
};

Student.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Student.h"
// 写实现 ,定义了另外一个方法
void Student::setAge(int age){// 实现 Student 的 setAge 方法
this->age = age;
}
void Student::setName(char* name){
this->name = name;
}
int Student::getAge(){
return this->age;
}
char* Student::getName(){
return this->name;
}

Simple.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "Student.h"
// 0 1 2 , 0 打印, 1 上传到后台, 2 友盟和服务器
void printLog(char* content,int){// 自己平台打印,产品说了下个版本可能要上传到服务器,友盟也要备一份
cout << content << endl;
// 补功能 有可能
}
void main(){
// new ,new 出来的是一个指针
Student *stu = new Student();
printLog("xxxx",0);// 100
printLog("xxxx", 1);// 100
printLog("xxxx", 2);// 100
stu -> setName("Darren");
stu -> age = 24;
cout << stu -> getName() << " , " << stu -> getAge() << endl;
getchar();
}
// 补充:开发过程中(重要)直接写的问题所在 Student.cpp 是一个单独类 Student.cpp
// 会编译成一个 so 库,必须要有一个头文件

6.构造函数/析构函数

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
// 1.构造函数
class Student
{
public:
// 构造函数
Student(){// 空参数构造函数
cout << "空参数构造函数"<< endl;
}

Student(char* name):age(0){// 一个参数构造函数, 相当于 this->age = 0
cout << "一个参数构造函数" << endl;
this->name = name;
this->age = 0;
}
Student(char* name, int age){// 两个参数构造函数
cout << "两个参数构造函数" << endl;
this->name = name;
this->age = age;
}
//默认参数赋值
// Student(char* name):age(0),sex(1){// 一个参数构造函数, 相当于 this->age = 0
// cout << "一个参数构造函数" << endl;
// this->name = name;
// this->age = 0;
// }

//析构函数:临终遗言,对象被回收的时候会被调用
//如果有在对象内部开辟堆内存,可以在析构函数中释放内存
~Student(){
cout << "析构函数" << endl;
// 释放内存
free(this->name);
this->name = NULL;
}

private:
int age;
char* name;
public:
int getAge(){
return this->age;
}

char* getName(){
return this->name;
}

void setAge(int age){
this->age = age;
}

void setName(char* name){
this->name = name;
}
};
/*
void main(){
// Student stu;// 1. 默认调用空参的构造函数
// stu.setAge(24);
// stu.setName("Darren");
// Student stu("Darren",24); // 2. 调用两个参数的构造函数
// 3. 用 new 关键字,返回的是一个 Student 的一级指针
// Student *stu = new Student("Darren",24);
// 4. 用 malloc 的方式,并没有调用空参的构造函数
// Student *stu = (Student*)malloc(sizeof(Student));
// stu->setAge(24);
// stu->setName("Darren");
//5.构造函数相互调用,注意:先会调用两个参数的构造函数,然后才会执行当前构造函数
Student *stu = new Student("Darren");
cout << stu -> getName() << " , " << stu->getAge() << endl;

getchar();
}

7.malloc、free、new、delete 区别

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// malloc、free、new、delete 区别
void main(){
// Student stu;// 栈中开辟内存
// malloc、free、 new、delete 都是开辟和释放内存
// 1. malloc/free 他们是一套, new/delete 它们也是配套
// 2. malloc/free 不会去调用构造函数和析构函数
// Student *stu = (Student*)malloc(sizeof(Student));
// free(stu);
// 3. new/delete 会调用构造函数和析构函数
// Student *stu = new Student();
// delete(stu);
// 4. 如果用了 new ,那么一定要记得 delete(释放内存)
getchar();
}

8.可变参数

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
#include <iostream>
#include <stdarg.h>
using namespace std;
// 1. 可以变参数
void sum(int count,...){// int ... , c++ ...
va_list vp;
// 可变参数开始方法,count 代表从哪里开始
va_start(vp, count);
int number = va_arg(vp,int);
cout << number << endl;//2
// 读取下一个
number = va_arg(vp, int);
cout << number << endl;//1
// 读取下一个 ,超出了默认是 0
number = va_arg(vp, int);
cout << number << endl;//0
}

void main(){
int number = sum(2,1,2);
cout << number << endl;
getchar();
}

//----------------------------------------------------------------------------------------------
int sum(int count, ...){// count数组长度
va_list vp;
// 可变参数开始方法,count 代表从哪里开始
va_start(vp, count);
int sum = 0;
for (int i = 0; i < count; i++)
{
sum += va_arg(vp, int);
}
// 结尾,释放内存
va_end(vp);
return sum;
}
void main(){
int number = sum(5,1,2,4);
cout << number << endl;
getchar();
}

9.静态属性static

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
class Student
{
public:
char* name;
int age;
// 静态
static int tag;// 定义
Student(){
tag = 12;
}
public:
static void change(){
tag += 12;
}
void change1(){
this -> change();
}
};
// 静态属性在 c++ 中必须要初始化,初始化必须这么写
int Student::tag = 12;
void main(){
Student stu;
// stu.tag = 12;
// c++ 操作静态语法 ::
// Student::tag += 12;
// Student::change();
stu.change1();
cout << Student::tag << endl;
getchar();
}
//总结:
// 静态 可以直接用类名去操作 ::
// 静态的属性必须要初始化 (实现)
// 静态的方法只能去操作静态的属性或者方法

10.类的大小

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
class A
{
public:
double b;
int a;
char c;
};
class B
{
public:
double b;
int a;
char c;
static double d;
};
class C
{
public:
double b;
int a;
char c;
C(int a){
this->a = a;
}
public:
int getA(){
return this->a;
}
};
// 1. 对象的大小与结构体的计算方式类似
// 2. static 静态变量和方法并没有算到类的大小中
// 3. 栈,堆,全局(静态,常量,字符串),代码区 ,类的大小只与普通属性有关系
void main(){
cout << "A 的大小:" << sizeof(A) << endl;
cout << "B 的大小:" << sizeof(B) << endl;
cout << "C 的大小:" << sizeof(C) << endl;
C c1(12);
C c2(24);
cout << c1.getA() << endl;
cout << c2.getA() << endl;
getchar();
}
  1. const 修饰函数
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

// this 指针:代表当前的对象,因为类的方法存放在代码区,大家一起共享的,所以要有 this 做区分
class Student{
public:
char* name;
int age;
public:
// this = const Student *const this
// 第一个 const :常量指针,代表值不能修改
// 第二个 const :指针常量,代表指针的地址不能修改
void change() const{// const 在() 之后主要用来限制 this 关键字
// this -> age += 12; // 不能对类的属性进行修改
// this = (Student*)0x0012;
}
// this = Student *const this
void change1(){
// this = (Student*)0x0012;
}
};
// 5. const 修饰函数
void main(){
Student stu;
stu.change();
cout << stu.age << endl;
getchar();
}

12.友元函数和类

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
class Person
{
private:
int age = 0;
public:
// 如果有自己写构造函数,那么会默认覆盖无参的构造函数
Person(int age){
this->age = age;
}
int getAge(){
return this->age;
}
// 友元函数的声明
friend void friend_change(Person *person, int age);
};
// 友元函数的实现
void friend_change(Person *person, int age){
// 修改一下 age 的值
// 在类的内部才能访问私有属性
// 如果该方法声明成友元函数那么是可以在外部访问其私有属性的
person->age = age;
}
void main(){
Person person = Person(24);
friend_change(&person,36);
cout << person.getAge() << endl;
getchar();
}

13.友元函数与普通函数的区别

Student.h

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
#ifndef STUDENT_H
#define STUDENT_H

class Student{
private:
int age;
char* name;
public:
// 静态属性的声明
static int tag;

public:
Student();
Student(char* name);
Student(char* name,int age);
// 析构函数
~Student();
// 拷贝构造函数
Student(const Student& stu);

public:
void setAge(int age);
void setName(char* name);

int getAge();
char* getName();

void print() const;

// 静态和友元
static void changeTag(int tag);
friend void changeAge(Student *stu,int age);
};
#endif // STUDENT_H

Student.cpp

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
#include "Student.h"
#include <iostream>

// 一个一个来实现
int Student::tag = 0;

// 构造函数
Student::Student(char* name) :Student(name,0){// :age(0) 赋默认值
this->name = name;
}

Student::Student(char* name,int age){
this->name = name;
this->age = age;
}

// 析构和拷贝构造函数
// 析构函数
Student::~Student(){

}
// 拷贝构造函数
Student::Student(const Student& stu){

}

// 普通方法
void Student::setAge(int age){
this->age = age;
}

void Student::setName(char* name){
this->name = name;
}

int Student::getAge(){
return this->age;
}

char* Student::getName(){
return this->name;
}

void Student::print() const{
std::cout << this->name << " , " << this->age << std::endl;
}

// 静态和友元
void Student::changeTag(int tag_replace){
tag = tag_replace;
}

// 实现友元方法
void changeAge(Student *stu, int age){
stu->age = age;
}

Simple.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <stdarg.h>
using namespace std;
#include "Student.h"

void main(){
Student *stu = new Student("Darren",24);
// Student::changeTag(36);
changeAge(stu,36);
stu->print();
delete(stu);
getchar();
}

14.友元类

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
class  ImageView
{
public: // B 是 A 的友元类
friend class Class;
private:
int a;
};

class Class
{
public:
ImageView aObj;
void changeA(int number){
aObj.a = number;//拿到友元类的私有属性
}
int getA(){
return aObj.a;
}
};

void main(){
Class b;
b.changeA(12);
cout << b.getA() << endl;
getchar();
}

15.operator重载运算符

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <iostream>

using namespace std;

/*
class Vector
{
public:
Vector(int x, int y){
this->x = x;
this->y = y;
}

Vector(const Vector &vector){
this->x = vector.x;
this->y = vector.y;
cout << "拷贝构造函数" << endl;
}
private:
int x;
int y;

public:
void setX(int x){
this->x = x;
}
void setY(int y){
this->y = y;
}

int getX(){
return this->x;
}
int getY(){
return this->y;
}

// 重载减号运算符
// 为什么要用引用,为了防止重复创建对象
// const 关键常量,为了防止去修改值
Vector operator - (const Vector &vector){
int x = this->x - vector.x;
int y = this->y - vector.y;
Vector res(x, y);
return res;// 不建议返回引用
}

// 自增减运算符
void operator ++ (){// ++X
this->x = this->x++;
this->y = this->y++;
}

void operator ++ (int){// X++
this->x = this->x++;
this->y = this->y++;
}

// 自减
// 输出运算符
friend ostream & operator << (ostream &_Ostr, const Vector &vector){
_Ostr << vector.x << "," << vector.y << endl;
return _Ostr;
}

// 条件运算符
bool operator == (const Vector &vector){
return (this->x == vector.x && this->y == vector.y);
}

// 括号运算符
};

// 定义在类的外面,一般来讲我们定义在类的里面
// 重载运算 + :operator +
Vector operator + (Vector vector1, const Vector vector2){
int x = vector1.getX() + vector2.getX();
int y = vector1.getY() + vector2.getY();
Vector vector(x,y);
return vector;
}

void main(){
Vector vector1(2, 3);
Vector vector2(2, 3);

// java 中 string + string

// char* str = "123" + "456";

// 重载运算符 +
// Vector vector = vector1 - vector2;

// Vector vector(1, 2);
// vector++;
// ++vector;

// cout << vector.getX() << " , " << vector.getY() << endl;
// cout << vector << vector;
bool isEqual = vector1 == vector2;
cout << isEqual << endl;
// 可以重载加其他对象 Person
getchar();
}

16.括号运算符

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
60
61
62
63
64
65
66
67
68
69
70

// 括号运算符
class Array
{
public:
Array(int size){
this->size = size;
this->array = (int*)malloc(sizeof(int)*size);
}
~Array(){
if (this->array){
free(this->array);
this->array = NULL;
}
}

Array(const Array& array){
this->size = array.size;
this->array = (int*)malloc(sizeof(int)*array.size);

// 值的赋值
for (int i = 0; i < array.size; i++)
{
this -> array[i] = array.array[i];
}
}

private:
int size;
int* array;

public:
void set(int index,int value){
array[index] = value;
}

int get(int index){
return this->array[index];
}

int getSize(){
return this->size;
}

// 操作符[]
int operator[](int index){
return this->array[index];
}
};

void printfArray(Array array){
for (int i = 0; i < array.getSize(); i++)
{
cout << array[i] << endl;
}
}

void main(){

Array *array = new Array(5);

array->set(0,0);
array->set(1, 1);
array->set(2, 2);

printfArray(*array);

delete(array);
getchar();
}

17.类继承

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
class Person{
// 变量修饰符
public:// 本类中使用
// protected :子类中能使用 (默认)
// public :公开,任何地方都可以
char* name;
int age;

public:
Person(char* name,int age){
this->name = name;
this->age = age;
cout << "Person 构造函数" << endl;
}

public:
void print(){
cout << this->name << " , " << this->age << endl;
}
};

// 类继承 语法 :
// 类继承修饰符 public
class Student : public Person
{
public:
// : Person(name,age) 调用构造函数初始化父类的属性
Student(char* name,int age):Person(name,age){// 调用父类构造函数
cout << "Student 构造函数" << endl;
}

void test(){
print();
}
};
void main(){
Student stu("Darren",24);

stu.name = "Jack";

getchar();
}

18.类继承修饰符

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
// 初始化属性
class Person{
// 变量修饰符
public:// 本类中使用
// protected :子类中能使用 (默认)
// public :公开,任何地方都可以
char* name;
int age;

public:
Person(char* name, int age){
this->name = name;
this->age = age;
cout << "Person 构造函数" << endl;
}

public:
void print(){
cout << this->name << " , " << this->age << endl;
}
};


class Student : public Person
{
private:
char* course;
public:
// : Person(name,age) 调用构造函数初始化父类的属性
// 不光可以给父类初始化属性,还可以给本类的属性进行初始化,用 , 隔开即可
Student(char* name, int age, char* course) :Person(name, age), course(course){// 调用父类构造函数
cout << "Student 构造函数" << endl;
}

void print(){
cout << "course: " << course << endl;
}
};

class Teacher: public Person
{
public:
Teacher(char*name,int age):Person(name,age){

}
};

void main(){
Student stu("Darren",24,"语文");
stu.print();
getchar();
}

19.属性初始化

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
#include <iostream>

using namespace std;

// 1. 属性初始化
/*
class Person
{
protected:
char* name;
int age;
public:
Person(char* name, int age){
this->name = name;
this->age = age;
}
};

class Course
{
private:// java String
string name;
public:
Course(string name){
this->name = name;
}

public:
string _name(){
return this->name;
}
};

class Student : public Person
{
private:
// char* courseName;
Course course;
public:
Student(char* name, int age, string courseName) : Person(name, age), course(courseName){ // 初始化父类的属性
// this->courseName = courseName;
}

void print(){
cout << name << "," << age << "," << course._name().c_str() << endl;
}
};
void main(){
Student *stu = new Student("Darren",24,"math");
delete stu;
getchar();
}

20.多继承

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
class Person{
private:
char * name;
public:
Person(char * name){
this->name = name;
}
char* _name(){
return this->name;
}
};
class Child
{
int age;
public:
Child(int age){
this->age = age;
}
int _age(){
return this->age;
}
};
class Student : public Person, public Child // 多继承 , 并没有实现
{
public:
Student(char* name,int age):Person(name),Child(age){
}
};

void main(){
// 构造函数:先父类 -> 再子类
// 析构函数:先子类 -> 再父类
Student *stu = new Student("Darren",24);
delete stu;
getchar();
}

21.多继承-二义性(virtual虚继承)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class A{
public:
char* name;
};
class B : virtual public A{ //不加virtual会运行时报错,virtual确保继承过来的相同属性或者函数,只存在一份拷贝
};
class C :virtual public A{
};
class D : public B ,public C
{
};
void main(){
D d;
d.name="darren";
cout<<d.name<<endl;
getchar();
}

22.多态

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
class Activity
{
public:
virtual void onCreate(){ // 支持多态,虚函数
cout << "Activity 中的 onCreate" << endl;
}
};

class MainActivity : public Activity
{
public:
void onCreate(){
cout << "MainActivity 中的 onCreate" << endl;
}
};

class WelcomeActivity : public Activity
{
public:
void onCreate(){
cout << "WelcomeActivity 中的 onCreate" << endl;
}
};

void startActivity(Activity* activity){
activity->onCreate();
}

void main(){
Activity *activity1 = new MainActivity();// 父类 = new 子类对象
Activity *activity2 = new WelcomeActivity();

// activity->onCreate();
// c++ 中的多态是怎样的,默认情况下不存在
// 父类指向子类的引用,重写 ,里氏替换原则
// 程序在编译期间并不知晓运行的状态(我需要运行那个函数),只要在真正运行的过程中才会去找需要运行的方法
startActivity(activity1);
startActivity(activity2);

// c++ 多态:动态多态(子父类),静态多态(函数的重载)(编译过程确定性的区别)
getchar();
}

23.继承中的抽象类

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
// java 中类似的 抽象类,接口 纯虚函数
class BaseActivity // 跟 java 中的抽象类一个概念
{
public:
void onCreate(){// 普通函数
initView();
initData();
}
// 子类必须要实现
virtual void initData() = 0;// 虚函数,声明,没有实现的,类似于 java 中的抽象方法,如果子类不实现会报错
virtual void initView() = 0;
};

// 如果不实现父类的纯虚函数,那么 MainActivity 也会变成抽象类,抽象类不允许实例化
class MainActivity : public BaseActivity
{
public:
void initData(){//实现
cout << "initData" << endl;
}
void initView(){
cout << "initView" << endl;
}
};

void main(){
BaseActivity *m_a = new MainActivity();
m_a->onCreate();
getchar();
}

24.接口

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
class ClickListener{// 所有的函数都是虚函数,那么就可以认为是接口
public:
virtual void click() = 0;
};
class ImageClickListener : public ClickListener
{
public :
void click(){
cout << "图片点击" << endl;
}
};
void click(ClickListener *listener){
listener->click();
}
void click(){
cout << "click点击" << endl;
}
// 函数指针 07 次
void click(void(*c)()){// 函数指针作为参数传递 返回值(函数名)(参数)
// 压缩开始
c();// 输出压缩进度
// 压缩结束
}

void main(){
// 函数指针的时候:回调可以用 指针函数作为回调,纯虚函数类进行回调(接口)
// ClickListener *listener = new ImageClickListener();
// listener->click();
// click(listener);
// 自己再去了解加深一下
click(click);
getchar();
}

25.构造函数和析构函数

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
class Person
{
protected:
char* name;
int age;
public:
Person(char* name, int age){
this->name = name;
this->age = age;
cout << "Person 的构造函数" << endl;
}
~Person(){
cout << "Person 的析构函数" << endl;
}
};

class Student : public Person
{
public:
Student(char* name, int age) : Person(name, age){ // 初始化父类的属性
cout << "Student 的构造函数" << endl;
}
~Student(){
cout << "Student 的析构函数" << endl;
}
};

void main(){
// 构造函数:先父类 -> 再子类
// 析构函数:先子类 -> 再父类
Student *stu = new Student("Darren",24);
delete stu;
getchar();
}

26.模版函数(java 中的泛型)

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
int add(int number1, int number2){
return number1 + number2;
}

double add(double number1, double number2){
return number1 + number2;
}

float add(float number1, float number2){
return number1 + number2;
}
// 模板函数 算法4 看一遍敲一遍
// 当普通函数和模板函数同时存在的时候,优先会调用普通函数
template <typename T>// 模板函数的定义
T add(T number1, T number2){
return number1 + number2;
}

void main(){
int sum1 = add(1,2);
cout << sum1 << endl;
int sum2 = add(1.0, 2.0);
cout << sum2 << endl;
int sum3 = add(1.0f, 2.0f);
cout << sum3 << endl;
getchar();
}

//day25

27.模板类 语法,跟模板函数非常类型

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
template <typename T>
class Callback
{
public:
void onError(){
}
void onSucceed(T result){
cout << result << endl;
}
};

// 模板类继承 ,子类如果也是模板类
// 如果子类不是模板类
class HttpCallback : public Callback<int>
{
};
template <class T>
class HttpCallback : public Callback<T>
{
};

void main(){
HttpCallback<int> *callback = new HttpCallback<int>();
callback->onSucceed(12);
getchar();
}

28.类型转换

1
2
3
4
5
1.1 static_cast 静态转换  用于基本数据类型之间的转换,如把int转换成char
1.2 const_cast 常量转换 用于修改常量的值
1.3 reinterpret_cat 强制类型转换 ,用于转换任意类型
1.4 dynamic_cast 动态转换 ,更安全,转换成功返回类型,失败返回空 ,
必须要包含多态类型和 static_cast 很类似,但是更安全
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
#include <iostream>
using namespace std;
class Person{
public:
string name;
int age;
public:
Person(string name, int age){
this->name = name;
this->age = age;
}
};

class Student : public Person{
public:
Student(string name, int age) : Person(name,age){
}
};

class Worker : public Person{
};

void main(){
double number1 = 20.02;
// 直接转换
// int number2 = number1;
// 1. 用于基本数据类型之间的转换,如把int转换成char
// int number2 = static_cast<int>(number1);
// cout << number2 << endl;
// 2. 把类型转换成另一种类型,用于类层次结构中基类和派生类之间指针或引用的转换
// Student *stu = new Student("Darren",24); // jobejct -> objectArray
// Person *person = stu;
// Person *person = static_cast<Person *>(stu);

// 待会再试
Person person = Person("Darren", 24);
// 转成Student
// Student stu = person;
cout << person.name.c_str() << " , " << person.age << endl;
getchar();
}

29.异常的处理

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
// NDK 异常总结
// 1. 在 c++ 层如果是自己写的代码或者调用别人的方法,记得要 try 住, 如果不 try 在 java 层 try 是没有意义的
// 2. 如果异常需要往外抛给 java 层,一定要按照java层抛异常的方式
// 3. 如果是自己写的 NDK 层的代码,最好抛自己写的异常,声明异常
// 4. 如果是做 c++/c , 或者是帮 c/c++ 写代码,最好抛系统定义好的异常或者继承系统的异常
// 5. 系统异常的体系 exception 基类 https://www.cnblogs.com/QG-whz/p/5136883.html
class Exception
{
public:
string msg;
public:
Exception(string msg){
this->msg = msg;
}
public:
const char *what(){
return this->msg.c_str();
}
};
// 异常的处理
void main(){
// c++ 中有自己一套异常的体系,不要去强记
// 但是 c++ 可以抛任何数据类型 try{}catch(数据类型 变量名){}
// throw 抛异常
try{
int i = -1;
if (i == 0){
throw Exception("出异常了");
}
if (i< 0){
throw 12.5f;
}
}
catch (int number){
cout << "捕捉到异常" <<number << endl;
}
catch (Exception exception){
cout << "捕捉到异常:" << exception.what() << endl;
}
catch (...){
cout << "捕捉到其他异常:" << endl;
}
getchar();
}

30字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void main(){
// C++ STL(Standard Template Library) 准模板库 :容器 + 迭代器 + 算法
// 1. 对象的构建
string str1 = "123";
string str2("123");
string str3(5, 'A');// 5 个 A = AAAAA
string *str4 = new string("123");

// cout << str1.c_str() <<endl;
// cout << str2.c_str() << endl;
// cout << str3.c_str() << endl;
// cout << str4->c_str() << endl;

// string 与 char* 相互之间转换 c_str()
// const char* c_str1 = str1.c_str();
// cout << c_str1 << endl;

// char* -> string
char* c_str = "Darren";
string str(c_str);// 对象
cout << str.c_str() << endl;

getchar();
}

31.字符串遍历

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
#define D_SCL_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

void main(){
string str("1234567");
// 1. 字符串的遍历
for (int i = 0; i < str.length(); i++)
{
cout << str[i] << endl;
}
// 迭代器遍历
for (string::iterator it = str.begin(); it < str.end(); it++)
{
cout << *it << endl;
}

try{
for (int i = 0; i < str.length()+2; i++)
{
cout << str.at(i) << endl;// 如果越界会抛异常
}
for (int i = 0; i < str.length()+2; i++)
{
cout << str[i] << endl;// 会导致程序宕机,AS里面是可以的
}
}
catch (...){
cout << "异常了" << endl;
}
getchar();
}

32.字符串添加,删除,替换,查找,大小写转换

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
void main(){
// 添加
string str1 = "123";
string str2 = "456";
// str1 = str1 + str2;
// str1.append(str2);
cout << str1.c_str() << endl;

// 删除
string str1 = "123 abc 123 abc 123";
// str1.erase(0,3);// 第一个参数:从哪里开始 ; 第二个参数:删除几个(默认值,字符串的结尾)
// 迭代器删除 2 bc 123 abc 123 解释
for (string::iterator it = str1.begin(); it<str1.begin()+3; it++)// 删除一个字后都会从头开始计算
{
str1.erase(it);
}
cout << str1.c_str() << endl;

//替换
string str1 = "123 abc 123 abc 123";
// 第一个参数:从哪里开始
// 第二个参数:替换几个
// 第三个参数:替换成谁
str1.replace(0,6,"1234");
cout << str1.c_str() << endl;

//查找
string str1 = "123 abc 123 abc 123";
// 查找谁,从哪里开始
// int position = str1.find("123",0);
// 从后面往前面查
int position = str1.rfind("123");
cout << position << endl;

//#include <algorithm>// STL 算法包
//#include <cctype>
//大小写转换
string str1 = "AAA abc BBB abc 123";
// 转换成大写
// transform(str1.begin(), str1.end(), str1.begin(), toupper);
transform(str1.begin(), str1.end(), str1.begin(), tolower);
cout << str1.c_str() << endl;

getchar();
}

33.vector 数组

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
#include <iostream>

#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <functional>
#include <set>

using namespace std;

/*
void main(){ // vector 数组

// vector
// 1. vector<int> v;
// 2. vector<int> v(10);
// 3. vector<int> v(10,0);
vector<int> v;
// 插入数据
// v.begin() 迭代器的开始位置
v.insert(v.begin(),12);
v.insert(v.begin(), 22);
v.insert(v.begin(), 32);

v.insert(v.end(), 42);

// 引用当左值当右值 (修改)
v.front() = 33;//最前
v.back() = 44;//最后

v.push_back(55);//最后处添加
// 移除最后的元素,并没有返回值
// v.pop_back();
// 通过迭代器位置进行移除
v.erase(v.begin());

// 获取数据 for 循环
for (int i = 0; i < v.size(); i++)
{
cout << v[i] << "\t";// 越界程序宕机
}
cout << endl;
//
for (int i = 0; i < v.size(); i++)
{
cout << v.at(i) << "\t"; // 越界抛异常 out_of_range
}
cout << endl;

// 通过迭代器
for (vector<int>::iterator it = v.begin(); it != v.end(); it++)
{
cout << *it << "\t"; // 越界抛异常 out_of_range
}
cout << endl;

getchar();
}

34.stack 栈, 先进后出 (链表,数组)

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
void main(){
stack<int> s;
// 压栈 ,压入指定位置
s.push(12);
s.push(22);
s.push(32);

// 并不能够通过角标去插入获取值,如果在开发的过程中如果的确需要通过角标去获取值,需要自定义
for (int i = 0; i < s.size(); i++)
{
cout << s. << endl;
}
// 迭代器也没有,并不支持循环的 ,非得循环

for (stack<int>::iterator it; i < s.size(); i++)
{
cout << s. << endl;
}

int top = s.top();
cout << top << endl;

// 弹出栈顶
s.pop();
top = s.top();
cout << top << endl;

while (!s.empty())
{
int top = s.top();
cout << top << endl;
s.pop();
}

getchar();
}

35.queue 队列 ,先进先出(链表,数组)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void main(){

queue<int> q;
q.push(12);
q.push(44);
q.push(32);

q.front() = 42;
cout << q.front() << endl;
q.pop();
cout << q.front() << endl;
// 最后,最后加入的
int back = q.back();
cout << back << end
while (!q.empty())
{
cout << q.front() << endl;
q.pop();
}

getchar();
}

36.优先级队列 (数据结构 数组,排序的方式堆排序)

1
2
3
4
5
6
7
8
9
10
11
12
13
//priority_queue优先队列是一种容器适配器,采用了堆这样的数据结构,保证了第一个元素总是整个优先队列中最大的(或最小的)元素。
void main(){
// int 存放的数据 vector<int> 数据类型(数组) greater 从大到小 less 从小到大
priority_queue<int,vector<int>,greater<int>> pq;
pq.push(12);
pq.push(44);
pq.push(32);
pq.push(10);
// 最大值
cout << pq.top() << endl;

getchar();
}

37.list 链表, 双向链表(有没有回环)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void main(){
list<int> l;
// 插入
l.push_front(11);
l.push_back(22);
l.insert(l.begin(),10);
// 修改
l.back() = 33;
l.front() = 44;
// 不能通过角标去访问,也不能去修改
// 移除
l.erase(l.begin());
l.pop_front();
l.pop_back();
// 循环
for (list<int>::iterator it = l.begin(); it != l.end(); it++)
{
cout << *it << endl;
}

getchar();
}

38.set 容器(红黑树结构) ,会对你存入的数据进行排序,但是不允许元素相同

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
void main(){
// set<int,less<int>> s;// 从小到大排序 ,默认就是 less
set<int, greater<int>> s;//从大到小排序

// 添加参数 , 不需要用迭代器,也不需要指定位置
s.insert(3);
s.insert(5);
s.insert(4);
// 重复的插入,并不会报错,返回两个值 插入迭代器的位置 ,是否插入成
pair<set<int, greater<int>>::iterator, bool> res = s.insert(5);
// res.first; 获取第一个参数
bool insert_succeed = res.second;
if (insert_succeed){
cout << "插入成功" << endl;
}
else{
cout << "插入失败" << endl;
}
// int count = s.count(5);
// s.find();

for (set<int>::iterator it = s.begin(); it != s.end(); it++)
{
cout << *it << endl;
}

getchar();
}
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
class Student
{
public:
string name;
int grade;

public:
Student(string name, int grade){
this->name = name;
this->grade = grade;
}
};

// 谓词(函数谓词) :按找特定的规则所编写的函数谓词
bool compare(const Student& _Left, const Student& _Right){
return _Left.grade > _Right.grade;
}

// 函数对象 仿函数
struct comparefuction
{
// 函数重载了 () 运算符,函数对象,仿函数
bool operator()(const Student& _Left, const Student& _Right) const{
return _Left.grade > _Right.grade;
}
};

// 基本数据类型 ,对象数据类型
void main(){
set<Student, comparefuction> s;

Student s1("Darren1", 2);
Student s2("Darren2", 9);
Student s3("Darren3", 5);

s.insert(s1);
s.insert(s2);
s.insert(s3);

for (set<Student>::iterator it = s.begin(); it != s.end(); it++)
{
cout << it->name.c_str() << "," << it->grade << endl;
}

getchar();
}

39.multiset容器 , 允许重复 ,用法和 set 一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void main(){
// set<int,less<int>> s;// 从小到大排序 ,默认就是 less
multiset<int, greater<int>> ms;

// 添加参数 , 不需要用迭代器,也不需要指定位置
ms.insert(3);
ms.insert(5);
ms.insert(4);
ms.insert(4);
ms.insert(3);

for (set<int>::iterator it = ms.begin(); it != ms.end(); it++)
{
cout << *it << endl;
}

getchar();
}

40.map

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
#include<iostream>
#include<map>
#include<set>
#include<vector>
#include<algorithm> // 预定义函数 ,已经实现好的一些算法头文件
using namespace std;
/*
void main(){
// map 会对 key 排序 ,二叉树算法
map<int, string> map1;

// 添加数据 - 第一种
map1.insert(pair<int,string>(01,"01"));

// 第二种方式
map1.insert(make_pair(02,"02"));

// 第三种方式
map1.insert(map<int,string>::value_type(03,"03"));

// 区别,如果用前面三种 key 重复添加 ,不生效
// map1.insert(map<int, string>::value_type(03, "30"));

// 第四种方式 = map1[key] = value
map1[04] = "04";
//常用的是第一种和第四种
// 第四种是会覆盖的
map1[04] = "40";

// 如果要判断添加是否成功 - 自己思考,参考上次课内容
map1[00] = "00";

// 循环 - 迭代器
for (map<int,string>::iterator it = map1.begin(); it != map1.end(); it++)
{
cout << it->first << " " << (it->second).c_str() << endl;
}

cout << " 遍历结束" << endl;

// 删除 ,查找
map<int,string>::iterator find_it = map1.find(0);

// cout << find_it->first << " " << (find_it->second).c_str() << endl;
if (find_it != map1.end()){
cout << find_it->first << " " << (find_it->second).c_str() << endl;
}
else{
cout << " 找不到 " << endl;
}

getchar();
}
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
//map案例
void main(){
multimap<int, string> map1;
// 案例,1 (11,12,13),2 (21,22,23),3(31,32,33)

map1.insert(pair<int, string>(1,"11"));
map1.insert(pair<int, string>(1, "12"));
map1.insert(pair<int, string>(1, "13"));

map1.insert(pair<int, string>(3, "31"));
map1.insert(pair<int, string>(3, "32"));
map1.insert(pair<int, string>(3, "33"));

map1.insert(pair<int, string>(2, "21"));
map1.insert(pair<int, string>(2, "23"));
map1.insert(pair<int, string>(2, "22"));


// 遍历
for (map<int, string>::iterator it = map1.begin(); it != map1.end(); it++)
{
cout << it->first << " " << (it->second).c_str() << endl;
}
cout << " 遍历结束" << endl;

// 分组查询 多个数据
multimap<int, string>::iterator find_it = map1.find(3);
while (find_it != map1.end()){
cout << find_it->first << " " << (find_it->second).c_str() << endl;
find_it++;
// 不是我们要找的内容
if (find_it == map1.end() || find_it -> first != 3){
break;
}
}

getchar();
}

41.一元谓词,二元谓词,仿函数

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
class Person
{
public:
string name;
char* test;
public:
Person(){}

Person(string name){
this->name = name;
test = (char*)malloc(12);
}

// 析构函数
~Person(){
free(test);
cout << "析构函数"<< &test << endl;
}

public:
void setName(string name){
this->name = name;
}

private:

};

// 3. 容器对象拷贝构造函数 , 就想存同一对象,在任何地方改变,集合的数据也相应发生变 (指针)
void main(){
// java 中把对象添加到了集合
// c++ 中会调用对象的拷贝构造函数,存进去的是另一个对象
// 第一个错误:没有默认的构造函数
// 第二个错误:析构函数也可能回调用多次,如果说在析构函数中释放内存,需要在拷贝构造函数中进行深拷贝
vector<Person> vector1;

Person person("Darren");
vector1.push_back(person);

person.setName("Jack");

Person person1 = vector1.front();

cout << person1.name.c_str() << endl;

getchar();
}


class Compare
{
// 重载了括号运算符
public:
void operator()(){
cout << "仿函数" << endl;
}
};

void compare1(){
cout << "普通函数" << endl;
}

// 函数对象(仿函数) 一元谓词,二元谓词
void main(){
Compare compare;

// 跟函数非常类似
compare();
// 普通函数调用
compare1();

getchar();
}

// 一元谓词
void print(int number){
cout << number << endl;
}

// 仿函数 - 一元谓词 (能够记录状态)
class PrintObj
{
public:
int count = 0;
public:
void operator()(int number){
cout << number << endl;
count++;
}
};

// 回调函数和仿函数的区别
void main() {

set<int> set1;
set1.insert(1);
set1.insert(2);
set1.insert(3);
set1.insert(4);

// for_each 迭代器 ,非常重要的一点就是:仿函数如果要保存记录状态,要确保对象一致,可以用返回值
// for_each(set1.begin(),set1.end(),print);
PrintObj printObj;
printObj = for_each(set1.begin(), set1.end(), printObj);
cout << "个数:" << printObj.count << endl;

getchar();
}


class CompareObj
{
public:
int count = 0;
public:
bool operator()(const string str1, const string str2){
return str1 < str2;
}
};

void main(){
// 二元谓词的仿函数
set<string, CompareObj> set1;
set1.insert("aaa");
set1.insert("aAa");
set1.insert("ccc");
set1.insert("ddd");
// 是否包含 aaa , 遍历比较 , 找方法
for (set<string>::iterator it = set1.begin(); it != set1.end(); it++)
{
cout << (*it).c_str() << endl;
}
getchar();
}

42.预定义函数对象和函数适配器 p118-p121

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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#define _SCL_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<set>
#include<functional>
#include<algorithm>
using namespace std;

/*
// 自定义重载 () 运算符
// 1. 预定义函数对象和函数适配器
void main(){
// c/c++ 提供了很多定义好的函数对象
// 常见的几个 less ,greater,plus,equal_to
plus<string> strAdd;
string str = strAdd("aaa","bbb");

// cout << str.c_str() << endl;

set<string, greater<string>> set1;
set1.insert("aaa");
set1.insert("bbb");
set1.insert("ccc");

// 判断是不是包含 aaa
// 怎么写仿函数,一定要确定好你的仿函数的参数
// bind2nd 函数适配器 , aaa 相当于 equal_to 中的 right

template<class _Ty = void>
struct multiplies
: public binary_function<_Ty, _Ty, _Ty>
{ // functor for operator*
_Ty operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator* to operands
return (_Left * _Right);
}
}
set<string, greater<string>>::iterator find_it = find_if(set1.begin(), set1.end(),bind2nd(equal_to<string>(),"aaa"));
if (find_it != set1.end()){
cout << "找到了" << (*find_it).c_str() << endl;
}
else
{
cout << "没有找到" << endl;
}

getchar();
}


// 1,种方式自定义仿函数(函数对象)
class Equal
{
private:
int equal_number;
public:
Equal(int equal_number){
this->equal_number = equal_number;
}
public:
bool operator()(const int& number){
return number == equal_number;
}
};

void main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(2);
vector1.push_back(4);
vector1.push_back(2);

// 找集合中 等于 2 的个数
int count = count_if(vector1.begin(), vector1.end(), Equal(2));
cout << "count = " << count << endl;

// 预定义好的函数对象 + 函数适配器
count = count_if(vector1.begin(), vector1.end(), bind2nd(equal_to<int>(),2));
cout << "count = " << count << endl;

getchar();
}


void print(int number){
cout << number << endl;
}

// 进行修改
int transform_print(int number){
// cout << number << endl;
return number + 3;
}

// foreach,transform,find,find_if,count,count_if,megre,sort,random_shuffle,copy,replace
// 常用预定义算法 循环,增,删,改,查
void main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(4);

// for_each(vector1.begin(), vector1.end(),print);
vector<int> vector2;
vector2.resize(vector1.size());

transform(vector1.begin(), vector1.end(), vector2.begin(), transform_print);

for_each(vector2.begin(), vector2.end(), print);

getchar();
}


// find,find_if
void main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(4);

vector<int>::iterator find_it = find(vector1.begin(), vector1.end(), 2);

if (find_it != vector1.end()){
cout << "包含" << endl;
}
else
{
cout << "不包含" << endl;
}

// 有没有大于2的,自定义函数对象,预定义函数对象+函数适配器,省略...

getchar();
}


// count,count_if
void main(){
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(2);
vector1.push_back(4);

int number = count(vector1.begin(), vector1.end(), 2);

cout << "等于2的个数:" << number << endl;

number = count_if(vector1.begin(), vector1.end(), bind2nd(less<int>(), 2));

cout << "小于2的个数:" << number << endl;

number = count_if(vector1.begin(), vector1.end(), bind2nd(greater<int>(), 2));

cout << "大于2的个数:" << number << endl;

getchar();
}

class _merge
{
public:
bool operator()(int number1,int number2){
return true;
}

};

void print(int number){
cout << number << endl;
}

// megre,sort,random_shuffle,copy,replace
void main(){

// 两个有序数组进行合并 - 归并排序
vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);

vector<int> vector2;
vector1.push_back(4);
vector1.push_back(5);
vector1.push_back(6);

vector<int> vector3;
vector3.resize(6);
merge(vector1.begin(), vector1.end(), vector2.begin(), vector2.end(), vector3.begin());
for_each(vector3.begin(), vector3.end(), print);

getchar();
}


void print(int number){
cout << number << endl;
}

void main(){

vector<int> vector1;
vector1.push_back(1);
vector1.push_back(3);
vector1.push_back(2);
vector1.push_back(4);

sort(vector1.begin(),vector1.end(),less<int>());
for_each(vector1.begin(), vector1.end(), print);

cout << "循环结束" << endl;

// 打乱循序
random_shuffle(vector1.begin(), vector1.end());
for_each(vector1.begin(), vector1.end(), print);

getchar();
}


void print(int number){
cout << number << endl;
}

// copy,replace
void main(){

vector<int> vector1;
vector1.push_back(1);
vector1.push_back(2);
vector1.push_back(3);
vector1.push_back(4);

vector<int> vector2;
vector2.resize(2);
copy(vector1.begin(), vector1.begin() + 2, vector2.begin());
// for_each(vector2.begin(), vector2.end(), print);

replace(vector1.begin(), vector1.end(), 2, 22);
for_each(vector1.begin(), vector1.end(), print);

getchar();
}

// 头部的封装 ToolBar 思考:自定义 View 4中样式
// 思考问题 ,方式去解决 NavigationBar (各种源码各种框架)

// 过度设计 :扩展性不高实用性不强 ,继承(代码)过于复杂,花哨

// 模板类 _InIt 名字 , _First, _Last , 返回值 是一个类型
// _Pr _Pred 这是什么?
template<class _InIt,
class _Pr> inline
_InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // find first satisfying _Pred
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Pred);
return (_Rechecked(_First,
_Find_if(_Unchecked(_First), _Unchecked(_Last), _Pred)));
}
template<class _InIt,
class _Pr> inline
_InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred)
{ // find first satisfying _Pred
for (; _First != _Last; ++_First)
// if 返回值是一个 bool 类型 ,往 _Pred 里面传递了一个参数 ,要么就是回调函数要么就是仿函数
if (_Pred(*_First))
break;
return (_First);
}