C语言是面向过程的,函数+结构体组成,C++是在C语言的基础上增加面向对象的能力,兼容C语言但是C语言不兼容C++,是Android中NDK开发的主要语言,对于学习NDK开发而言重要性是不言而喻的,接下来总结C++的学习,欢迎一起学习和交流~
打印日志
1 | void print() { |
交换两个数
1 | // c的交换方式 |
通过内存地址修改某个值
1 | int n1 = 999; |
定义结构体
1 | typedef struct { |
函数重载
1 | int add(int number1,int number2 ){ |
类的定义
- Teacher.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
43
44
45
46
47
using namespace std;
class Person{
private:
char *name;
int age;
public:
Person(char * name, int age):name(name){
this -> age = age;
cout << "Person 构造函数" << endl;
}
void print(){
cout << this -> name << "," << this -> age << endl;
}
};
// 默认私有继承,子类中可以访问父类的成员,类外不行
// 公开继承,子类在类外也可以访问父类的成员 class Student:public Person
class Student: Person{
private:
char * course;
Student(char * name, int age, char * course): Person(name, age),course(course){
cout << "Student 构造函数" << endl;
}
public:
void test(){
print();
}
// 构造函数顺序:Person,Student,析构函数顺序Student,Person
~Student(){
cout << "Student 析构函数" << endl;
}
};
class Teacher{
private:
char *name;
int age;
public:
void setAge(int age);
void setName(char *name);
int getAge();
char* getName();
// 静态变量声明再实现
static int id;
// 友元函数可以访问/修改所有私有成员
friend void updateAge(Teacher *teacher, int age);
}; - Teacher.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
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
using namespace std;
public:
int Teacher::id = 9
// 不需要::
void updateAge(Teacher *teacher, int age){
teacher -> age = age;
}
void Teacher::setAge(int age){
this->age = age;
}
void Teacher::setName(char *name){
this -> name = name;
}
int Teacher::getAge(){
return this -> age;
}
char* Teacher::getName(){
return this -> name;
}
// 先调两个参数的构造函数,再调用一个参数的构造函数
Teacher(char *name):Teacher(name, 87){
this.name = name;
}
// 拷贝构造函数,被const修饰只能写在类中访问私有成员
Teacher(const Teacher &teacher){
this -> age = teacher.age;
// 浅拷贝
// this -> name = teacher.name;
// 如果存在堆成员采用深拷贝
this -> name = (char *)malloc(sizeof(char*) * 10);
strcpy(this -> name, teacher.name);
}
Teacher(char *name, int age){
// 堆区创建的name
this -> name = (char *)malloc(sizeof(char*) * 10);
strcpy(this -> name, name);
this.age = age;
}
~Teacher(){
// 释放堆区创建的属性
if (this -> name){
free(this -> name);
this -> name = NULL;
}
}
int main(){
// 栈空间分配内存
Teacher teacher;
teacher.setAge(99);
teacher.setName("李华");
cout << "name:" << teacher.getName() << ", age:" << teacher.getAge() << endl;
// free 不会调析构函数,malloc不会调构造函数
// 堆空间分配内存
Teacher *teacher2 = new Teacher(); //堆区 手动释放
teacher2 ->setAge(88);
teacher2 ->setName("李华成");
// 堆空间的内存需要手动释放
if (teacher2){
delete teacher2; // 析构函数一定执行
teacher2 = NULL;
}
Teacher teacher1("张三",34); //栈区 弹栈自动释放
// 不会调用拷贝构造函数
// Teacher teacher2;
// teacher2 = teacher1;
Teacher teacher2 = teacher1; // 调拷贝构造函数
Teacher *teacher1 = new Teacher("李四",35);
Teacher *teacher2 = teacher1; // 不会调拷贝构造函数
int number = 9;
int number2 = 8;
// 常量指针
const int *numberP1 = &number;
*numberP1 = 100; // 不允许修改常量指针存放地址对应的值
numberP1 = &number2; // 允许修改常量指针存放的地址
// 指针常量
int* const numberP2 = &number;
*numberP2 = 100; // 允许修改指针常量存放地址对应的值
numberP2 = &number2; // 不允许修改指针常量存放的地址
// 常量指针常量
const int* const numberP3 = &number;
*numberP3 = 100; // 不允许修改常量指针常量存放地址对应的值
numberP3 = &number2; // 不允许修改常量指针常量存放的地址
return 0;
}自定义命名空间
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17namespace MyNameSpace1{
namespace MyNameSpace2{
namespace MyNameSpace3{
void out(){
cout << "" << endl;
}
}
}
}
int main(){
// 第一种调用方式
using namespace MyNameSpace1::MyNameSpace2::MyNameSpace3;
out();
// 第二种调用方式
// MyNameSpace1::MyNameSpace2::MyNameSpace3::out();
return 0;
}可变参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using namespace std;
void sum(int count, ...){
va_list vp; // 可变参数的动作
// count 内部需要一个存储地址参考值,否则无法处理存放参数的信息,也用于循环遍历
va_start(vp, count);
int number = va_arg(vp, int);
cout << number << endl;
number = va_arg(vp, int);
cout << number << endl;
number = va_arg(vp, int);
cout << number << endl;
va_end(vp);
}
int main(){
sum(54,6,7,8)
return 0;
}友元类
- java反射的实现原理 native层利用友元类访问私有成员
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
using namespace std;
class ImageView{
private int viewSize;
friend class Class; // 声明Class为友元类
};
class Class{
public ImageView imageView;
void changeViewSize(int size){
imageView.viewSize = size;
}
int getViewSize(){
return imageView.viewSize
}
};
int main(){
Class imageViewClass;
imageViewClass.changeViewSize(600);
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
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
95class Position{
private:
int x, y;
public:
Position(int x, int y):x(x), y(y) {}
void setX(int x){
this -> x = x;
}
void setY(int y){
this -> y = y;
}
int getX(){
return this -> x;
}
int getY(){
return this -> y;
}
// 如果没有&会创建副本,影响性能
Position operator + (Position &position) {
int x = this -> x + position.x; // 类里可以访问私有成员
int y = this -> y + position.y;
return Position(x, y);
}
void operator ++(){ //++对象
this -> x = this -> x + 1;
this -> y = this -> y + 1;
}
void operator ++ (int) { //对象++
this -> x = this -> x + 1;
this -> y = this -> y + 1;
}
friend void operator << (ostream &_START, Position position){
_START << position.x << "," << position.y << endl;
}
friend ostream & operator >> (ostream &_START, Position position){
_START << position.x << "," << position.y << endl;
return _START; // 可多次打印
}
friend istream & operator >> (istream &_START, Position position){
_START >> position.x;
_START >> position.y;
return _START; // 可多次打印
}
};
class ArrayClass {
private:
int size = 0;
int *arrayValue;
public:
void set(int index, int value){
arrayValue[index] = value;
size += 1;
}
int getSize(){
return this -> size;
}
int operator[](int index){
return this -> arrayValue[index];
}
void printfArrayClass(ArrayClass arrayClass){
for (int i = 0; i < arrayClass.getSize(); ++i){
cout << arrayClass[i] << endl;
}
}
};
int main(){
Position position1(100, 200);
Position position2(200, 300);
Position res = position1 + position2;
cout << res.getX() << "," << res.getY() << endl;
Position pos(1, 2);
pos ++;
++ pos;
cout << pos.getX() << "," << pos.getY() << endl;
cout >> position2 >> position2 >> position2;
Position position;
cin >> position;
cout << position.getX() << "," << position.getY() << endl;
ArrayClass arrayClass;
arrayClass.set(0, 1000);
arrayClass.set(1, 2000);
arrayClass.set(2, 3000);
printfArrayClass(arrayClass);
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
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
using namespace std;
class BaseActivity1{
public:
void onCreate(){
cout << "BaseActivity1 onCreate" << endl;
}
void onStart(){
cout << "BaseActivity1 onStart" << endl;
}
};
class BaseActivity2{
public:
void onCreate(){
cout << "BaseActivity2 onCreate" << endl;
}
void onStart(){
cout << "BaseActivity2 onStart" << endl;
}
};
class BaseActivity3{
public:
void onCreate(){
cout << "BaseActivity3 onCreate" << endl;
}
void onStart(){
cout << "BaseActivity3 onStart" << endl;
}
};
class MainActivity1: public BaseActivity1,BaseActivity2,BaseActivity3{
void onCreate(){
cout << "MainActivity1 onCreate" << endl;
}
};
int main(){
MainActivity1 mainActivity1;
mainActivity1.onCreate();
// mainActivity1.onStart(); 有歧义,不知道调哪个父类的onStart,子类重写onStart就没问题
mainActivity1.BaseActivity1::onStart();
mainActivity1.BaseActivity2::onStart();
mainActivity1.BaseActivity3::onStart();
return 0;
}
class Object{
public:
int number;
};
// 虚继承解决歧义问题
class BaseActivity1:virtual public Object{
};
// 虚继承解决歧义问题,原理是把多个变量化成一份
class BaseActivity2:virtual public Object{
};
class Son :public BaseActivity1,public BaseActivity2{
public:
int number; // 覆盖父类number
}
int main(){
Son son;
son.BaseActivity1::number = 1;
son.BaseActivity2::number = 1;
son.number = 1;
return 0;
}多态
- 重写和重载
- 同一个方法有不同的实现,父类指向子类
- 动态多态:程序在运行期间才确定调用哪个类的函数
- C++默认关闭多态,在父类上给方法增加virtual关键字开启多态
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
using namespace std;
class BaseActivity{
public:
virtual void onStart(){
cout << "BaseActivity onStart" << endl;
}
};
class HomeActivity: public BaseActivity{
public:
void onStart(){
cout << "HomeActivity onStart" << endl;
}
};
class LoginActivity: public BaseActivity{
public:
void onStart(){
cout << "LoginActivity onStart" << endl;
}
};
void startToActivity(BaseActivity *baseActivity){
baseActivity -> onStart();
}
void add(int number1, int number2){
cout << number1 + number2 << endl;
}
void add(float number1, float number2){
cout << number1 + number2 << endl;
}
void add(double number1, double number2){
cout << number1 + number2 << endl;
}
int main(){
BaseActivity *homeActivity = new HomeActivity();
BaseActivity *loginActivity = new LoginActivity();
startToActivity(homeActivity);
startToActivity(loginActivity);
if (homeActivity && loginActivity) delete homeActivity; delete loginActivity;
add(100, 100);
add(1.1f, 2.1f);
add(23.2, 21.2);
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using namespace std;
class BaseActivity{
private:
void setContentView(String layoutId){
cout << "解析布局文件,反射" << endl;
}
public :
void onCreate(){
setContentView(getLayoutId());
initView();
initData();
initListener();
}
//纯虚函数就是抽象函数,必须实现,虚函数virtual String getLayoutId();不是必须实现的
virtual String getLayoutId() = 0;
virtual void initView() = 0;
virtual void initData() = 0;
virtual void initListener() = 0;
};
// 如果子类没有实现纯虚函数就是抽象类,不能实例化
class MainActivity: public BaseActivity{
String getLayoutId(){
return "R.layout.activity_main";
}
void initView(){
}
void initData(){
}
void initListener(){
}
};
int main(){
MainActivity mainActivity;
return 0;
}全纯虚函数
- 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;
Class Student{
int _id;
string name;
int age;
};
// 定义接口
class Student_DB{
virtual void insertStudent(Student student) = 0;
virtual void deleteStudent(int id) = 0;
virtual void updateStudent(int id, Student student) = 0;
virtual void queryStudent(Student student) = 0;
}
// 接口的实现类
class Student_DBImpl: public Student_DB{
public:
void insertStudent(Student student){
}
void deleteStudent(int id){
}
void updateStudent(int id, Student student){
}
Student queryStudent(Student student){
}
}
int main(){
Student_DBImpl student_DBImpl;
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// 返回的数据对象
class SuccessBean {
public:
String username;
String userpwd;
SuccessBean(String username, String userpwd):username(username),userpwd(userpwd){}
}
// 回调接口
class ILoginResponse{
public:
virtual void loginSuccess(int code, string message, SuccessBean successBean) = 0;
virtual void loginError(int code, string message) = 0;
}
// 登录操作
void loginAction(String name, String pwd, ILoginResponse loginResponse){
if (name.empty() || pwd.empty()){
cout << "用户名或密码为空" << endl;
return;
}
if ("admin" == name && "123" == pwd){
loginResponse.loginSuccess(200, "登录成功", SuccessBean(name, "恭喜你成功登入"));
loginResponse.loginError(404, "用户名或密码错误");
}
}
// 接口的实现类
class ILoginResponseImpl: public ILoginResponse{
public:
void loginSuccess(int code, string message, SuccessBean successBean){
cout << "登录成功" << "code:" << code << "message" << message << "successBean" << successBean.username << "," << successBean.userpwd << endl;
}
void loginError(int code, string message){
cout << "登录失败" << "code:" << code << "message" << endl;
}
}
int main(){
string username;
cout << "请输入用户名.." << endl;
cin >> username;
string userpwd;
cout << "请输入密码.." << endl;
cin >> userpwd;
ILoginResponseImpl iLoginResponseImpl;
loginAction(username, userpwd, iLoginResponseImpl);
return 0;
}泛型
1
2
3
4
5
6
7
8
9
10
11template <typename TT>
void addAction(TT n1, TT n2){
cout << "模版函数:" << n1 + n2 << endl;
}
int main(){
addAction(1, 2);
addAction(10.2f, 20.3f);
addAction(545.34, 324.3);
return 0;
}