c和c++联系
- c++代码可以混编c代码,既可以写c也可以调用c
- c++面向对象,c面向过程
- 开源框架大部分都是基于c++写的
打印1
2
3
4
5
6
7
8
9
10
using namespace std;
void main() {
//打印
//cout << "hello world " << endl;//换行
cout << "hello world " ;//不换行
}
常量1
2
3
4
5
6
7
8
9void main() {
//常量
const int number = 0;
//在c文件,这里可以通过指针修改值,但是在c++中不能通过地址修改值,一般编译器编译不能通过,但是某一些编译器可以,但是也不能修改值
//int *number_p = &number;
//*number_p = 20;
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
47
48
49
using namespace std;
//通过指针来变换
void swap(int *num1,int* num2) {
int temp = 0;
temp = *num1;
*num1 = *num2;
*num2 = temp;
}
//通过引用来变换
void swap(int &num1, int& num2) {
cout << "number1p = " << &num1 << " number2p = " << &num2 << endl;//number1p = 00BBFA08 number2p = 00BBF9FC
int temp = 0;
temp = num1;
num1 =num2;
num2 = temp;
}
void main() {
//引用:四驱模型值的拷贝,引用其实是地址赋值,可以看成同一块内存的另外一个变量
//交换值
int number1 = 10;
int number2 = 20;
//通过指针
//swap(&number1,&number2);
//通过引用
cout << " number1p = " << &number1 << " number2p = " << &number2 <<endl; // number1p = 00BBFA08 number2p = 00BBF9FC
swap(number1,number2);
cout << "number1 = " << number1 << " number2 = " << number2 << endl;// number1 = 20 number2 = 10
//加深理解
int a = 10;
int b = a; //赋值 b 和 a分别指向不同的内存
cout << "ap = " << &a << " bp = " << &b << endl;// ap = 010FF730 bp = 010FF724
int& c = a;//引用 a和c都指向一块地址
cout << "ap = " << &a << " cp = " << &c << endl;// ap = 010FF730 cp = 010FF730
c = 20;
cout << "a = " << a << " c = " << c << endl;//a = 20 c = 20
getchar();
}
常量引用
1 |
|
重载 :c不支持重载 ,c++支持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
using namespace std;
//重载
//int add(int number1, int number2) {
//
// return number1 + number2;
//}
int add(int number1, int number2,bool cache = false) {
cout << cache << endl;
return number1 + number2;
}
int add(int number1, int number2,int number3) {
return number1 + number2 + number3;
}
void main() {
int number1 = 10;
int number2 = 20;
int number3 = 30;
int sum1 = add(number1, number2);
int sum2 = add(number1, number2 , number3);
printf("%d , %d", sum1, sum2);
getchar();
}
类 JAVA里的Class1
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
using namespace std;
class Student{
private: // 私有 包装,影响下面所有的属性或者方法
char * name;
int age;
public://影响下面所有的方法或者属性
void setAge(int age){
this->age = age;
}
void setName(char*name) {
this->name = name;
}
int getAge() {
return this->age;
}
char * getName() {
return this->name;
}
};
void main() {
Student stu;
stu.setAge(25);
cout << stu.getAge() << endl;
Student *student = new Student();
student->setAge(24);
cout << student->getAge() << endl;
getchar();
}
注意:在开发过程中,cpp
或者c
会被编译为dll
或者so
供其调用者使用,一般把public
的函数定义到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
35
36
37
38
39
40
41
42
43class Student{
public:
//1.
Student() {};
//2.
Student(char * name):age(0) { // 相当于thix->age = 0
this->name = name;
};
//3.
//构造函数相互调用 先调用两个参数的,在调用一个参数的
Student(char*name) :Student(name,0) { // 相当于thix->age = 0
};
//4.
Student(char*name,int age) {
this->name = name;
this->age = age;
};
private:
char * name;
int age;
public:
void setAge(int age){
this->age = age;
}
void setName(char*name) {
this->name = name;
}
int getAge() {
return this->age;
}
char * getName() {
return this->name;
}
};
析构函数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 Student{
public:
Student() {};
Student(char*name,int age) {
this->name = (char*)malloc(sizeof(char)*100);
strcpy(this->name,name);
this->age = age;
};
//析构函数:对象被回收的时候会被调用,只能有一个,不能有参数
~Student() {
//释放内存 这里name使用malloc举个例子
free(this->name);
}
private:
char * name;
int age;
public:
void setAge(int age){
this->age = age;
}
void setName(char*name) {
this->name = name;
}
int getAge() {
return this->age;
}
char * getName() {
return this->name;
}
};
malloc free new delete区别
malloc/free
一起用new/delete
一起用- malloc/free不会调用构造函数和析构函数,new/delete会调用构造函数和析构函数
- 如果用了new,一定要记得delete释放内存
拷贝构造函数1
2
3
4Class(const Class& C)
{
//..赋值
}
https://blog.csdn.net/lwbeyond/article/details/6202256
可变参数 java的Object…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
using namespace std;
//可变参数
int sum(int 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;
}
int main()
{
cout<<sum(3, 2, 3, 4)<<endl;
getchar();
return 0;
}
static1
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
using namespace std;
class Student
{
public:
char * name;
int age;
static int tag;
Student() {
tag = 10;
}
static void change() {
tag += 20;
}
void change2() {
tag += 20;
}
};
//静态属性 在c++中必须初始化,初始化必须这么写
int Student::tag =15;
int main()
{
cout << Student::tag << endl;//15
Student stu;
cout << Student::tag << endl;//10
Student::change(); //静态函数调用静态变量
cout << Student::tag << endl;//30
stu.change2(); //非静态函数调用静态变量
cout << Student::tag << endl;//50
getchar();
return 0;
}
// 1. 调用使用 双冒号 ::
// 2. 静态属性 必须初始化
// 2. 静态函数只能操作静态的相关函数和属性
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
27
28
29
30
31
32
33
34
35
36
37
using namespace std;
class C
{
public:
int age;
public:
const void change() {
this->age += 12;
}
//const 在()之后主要用来限制this关键字
void change2() const {
//this->age += 12; //不能对类的属性进行修改
}
C(int age) {
this->age = age;
}
};
int main()
{
C *c = new C(15);
c->change();
cout << c->age << endl;
getchar();
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
using namespace std;
class Person
{
public:
Person(int age) {
this->age = age;
};
int getAge() {
return this->age;
}
//友元函数 申明之后,friend_change就可以调用私有属性
friend void friend_change(Person * person, int age);
private:
int age = 0;
};
void friend_change(Person * person, int age) {
//age private修饰,在类的内部才能访问私有函数。如果非要访问,就得用到友元函数
//如果该方法设置为友元函数,那么在外部可以访问其私有属性
person->age = age;
}
int main()
{
Person person = Person(24);
friend_change(&person,20);
cout << person.getAge() << endl;//20
getchar();
return 0;
}
构造函数,析构函数,拷贝构造函数,普通函数,静态函数,友元函数实现
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
35
36
37
38
class Student
{
private:
int age;
int time;
public:
//静态属性的申明
static int tag;
public:
//构造函数
Student();
Student(int age);
Student(int time, int age);
//析构函数
~Student();
//拷贝构造函数
Student(const Student &student );
public:
void setAge(int age);
void setTime(int time);
int getAge();
int getTime();
void print() const;
//静态函数
static void changeTag(int tag_replease);
//友元函数
friend void changeAge(Student* stu,int age);
};
实现类 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
57
58
59
60
61
62
63
64
65
//实现类,不一定都要全部实现
//静态属性的申明
int Student::tag = 0;
//构造函数
Student::Student(){
};
Student::Student(int age):time(200) { //time默认赋值
this->age = age;
}
Student::Student(int age,int time) {
this->age = age;
this->time = time;
}
//析构函数
Student::~Student() {
//资源回收
}
//拷贝构造函数
Student::Student(const Student& student) {
}
//普通方法
void Student::setAge(int age) {
this->age = age;
}
void Student::setTime(int time) {
this->time = time;
}
int Student::getAge() {
return this->age;
}
int Student::getTime() {
return this->time;
}
// const函数
void Student::print() const {
//this->age = 20;//不能操作this
std::cout << this->age << " " << this->time << " "<< tag << std::endl;
}
//静态函数
void Student::changeTag(int tag_replease) {
tag = tag_replease;
}
//友元函数 不需要加 Student::
void changeAge(Student* stu, int age) {
stu->age = age;
}
demo:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void main() {
Student* stu = new Student(24, 1000);
//调用const函数
stu->print();
//调用静态函数
Student::changeTag(36);
stu->print();
//调用友元函数
changeAge(stu, 37);
stu->print();
delete(stu);
getchar();
}
友元类 :java的反射获取属性可以理解为就是有一个Class
类的友元类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
30class ImageView {
public:
//申明Class是ImageView 的友元类
friend class Class;
private:
int age;
};
class Class{
public:
void changeAge(int age) {
//正常情况下这是不能直接用的,申明友元类就可以用了
aObj.age = age;
}
int getAge() {
//正常情况下这是不能直接用的,申明友元类就可以用了
return aObj.age;
}
private :
ImageView aObj;
};
void main() {
Class b;
b.changeAge(10);
std::cout << b.getAge() << std::endl; // 10
getchar();
}
操作运算符
1 |
|
类的继承 : 类继承,构造函数调用顺序:先父类 -> 再子类
,析构函数调用顺序 : 先子类 -> 再父类
1 |
|
1 |
|
多继承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
using namespace std;
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;
}
};
// 多继承,在 java 里面是不允许多继承 , c++ 是可以的,但是你也不能有二义性(歧义)
class Student : public Person, public Child // 多继承 , 并没有实现(接口)
{
public:
Student(char* name,int age):Person(name),Child(age){
}
};
虚继承:解决二义性
1 | class A{ |
多态:c++里面分为动态多态(子父类 需要virtual修饰),静态多态(函数的重载),区别是编译过程确定性。
1 | class Activity |
抽象类,抽象函数
1 | // java 中类似的 抽象类,接口 纯虚函数 |
接口
1 |
|
模板函数 : java 中的泛型
1 | // 模板函数的定义 |
模板类
1 | template <typename T> class Callback{ |
如果开发中涉及到模板类,申明和实现要写在同一个类里面: hpp = h + cpp/c (编译)
例如:c++实现ArrayList
ArrayList.hpp
1 |
|
使用的时候引入ArrayList.hpp
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
extern "C"
JNIEXPORT void
JNICALL
Java_com_zzw_demo_MainActivity_test(
JNIEnv *env,
jobject /* this */) {
ArrayList<int> *list = new ArrayList<int>();//
for (int i = 0; i < 100; ++i) {
list->add(i);
}
for (int i = 0; i < list->size(); ++i) {
__android_log_print(ANDROID_LOG_ERROR,"TAG","i = %d",list->get(i));
}
delete(list);
}
异常处理
1 |
|
字符串常见操作
创建
1 | void main(){ |
遍历
1 | void main(){ |
添加
1 | void main(){ |
删除
1 | void main(){ |
替换
1 | void main(){ |
查找
1 |
|
大小写转换
1 | void main(){ |
STL标准模板库 : 容器+迭代+算法
- 思想:集合,迭代器,算法 进行分离
vector容器(数组)
https://zh.cppreference.com/w/cpp/container/vector1
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容量
向量大小: vec.size();
向量真实大小: vec.capacity();
向量判空: vec.empty();
修改
末尾添加元素: vec.push_back();
末尾删除元素: vec.pop_back();
任意位置插入元素: vec.insert();
任意位置删除元素: vec.erase();
清空向量元素: vec.clear();
迭代器
开始指针:vec.begin();
末尾指针:vec.end(); //指向最后一个元素的下一个位置
指向常量的末尾指针: vec.cend();
元素的访问
下标访问: vec[1]; //并不会检查是否越界
at方法访问: vec.at(1); //以上两者的区别就是at会检查是否越界,是则抛出out of range异常
访问第一个元素: vec.front();
访问最后一个元素: vec.back();
stack容器(链表,数组)
https://zh.cppreference.com/w/cpp/container/stack
queue容器(数组,链表)
https://zh.cppreference.com/w/cpp/container/queue
list容器(链表)
https://zh.cppreference.com/w/cpp/container/list
set容器(红黑树,元素不重复)
https://zh.cppreference.com/w/cpp/container/set
multiset容器(元素可重复)
https://zh.cppreference.com/w/cpp/container/multiset
map容器(key不能重复)
https://zh.cppreference.com/w/cpp/container/map
multimap容器(以key分组)
https://zh.cppreference.com/w/cpp/container/multimap
对象添加到容器需要注意的:
- java 中把对象添加到了集合,c++ 中会调用对象的拷贝构造函数,存进去的是另一个对象
- 在c++中将对象加入到容器,需要有默认的构造函数
- 析构函数也可能回调用多次,如果说在析构函数中释放内存,需要在拷贝构造函数中进行深拷贝
仿函数
1 |
|
谓词
一元谓词
1 |
|
二元谓词
1 |
|
预定义函数对象(自定义重载 () 运算符),函数适配器
1 |
|
1 |
|
- foreach,transform
1 |
|
- find,find_if
1 |
|
- count,count_if
1 |
|
- megre: 两个有序数组进行合并 - 归并排序
1 |
|
- soft,random_shuffle
1 | void print(int number) { |
- copy,replace
1 |
|