0%

死磕C++


C语言是面向过程的,函数+结构体组成,C++是在C语言的基础上增加面向对象的能力,兼容C语言但是C语言不兼容C++,是Android中NDK开发的主要语言,对于学习NDK开发而言重要性是不言而喻的,接下来总结C++的学习,欢迎一起学习和交流~


打印日志

1
2
3
4
5
6
void print() {
// c的打印方式
printf("c++ 语言的学习!\n");
// c++的打印方式,endl == \n
cout << "c++ 语言的学习!" << 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
// c的交换方式
void numberChange(int *num1, int *num2){
int temp;
temp = *num1;
*num1 = *num2;
*num2 = temp;
}
// c++的交换方式
void numberChange2(int &number1,int &number2){
// 内存地址与外部一致
cout << "n1内存地址:" << &number1 << ", n2内存地址:" << &number2 <<endl;

int temp;
temp = number1;
number1 = number2;
number2 = temp;
}
int main(){
int num1 = 10;
int num2 = 20;
// numberChange(&num1, &num2);
// cout << "n1:" << num1 << ", n2:" << num2 << endl;
cout << "n1内存地址:" << &num1 << ", n2内存地址:" << &num2<<endl;
numberChange2(num1, num2);
cout << "n1:" << num1 << ", n2:" << num2 << endl;
return 0;
}

通过内存地址修改某个值

1
2
3
4
5
6
7
8
9
10
11
12
int n1 = 999;
int n2 = n1;
// n1 n2内存地址不同
cout << &n1 << "---" << &n2 << endl;

int n3 = 999;
int &n4 = n3;
// n3 n4内存地址相同
cout << &n3 << "---" << &n4 << endl;
n4 = 777;
// n3 n4都改为777
cout << n3 << "---" << n4 << endl;

定义结构体

1
2
3
4
5
6
7
8
typedef struct {
char name[20];
int age;
}Student;
int main(){
Student student = {"小明", 30};
return 0;
}

函数重载

1
2
3
4
5
6
7
8
9
10
11
12
int add(int number1,int number2 ){
return number1 + number2;
}

int add(int number1,int number2,int number3){
return number1 + number2 + number3;
}

// 支持默认形参,直接重载1-4个参数方法
//int add(int number1 = 1,int number2 = 2,int number3 = 3, int number4 = 4){
// return number1 + 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
    #include <iostream>
    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
    #include "Teacher.h"
    #include <string.h>
    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
    17
    namespace 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
    #include <stdarg.h> // 支持可变参数
    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
    # include<iostream>
    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
    95
    class 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
    #include <iostream>
    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
    #include <iostream>
    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
    #include <iostream>
    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
    #include<iostream>
    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
    11
    template <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;
    }