NDK開(kāi)發(fā):C++基礎(chǔ)

一、命名空間

standard:標(biāo)準(zhǔn)命名空間

using namespace std;

命名空間類(lèi)似于java中的包。

  1. 自定義命名空間
namespace NSP_A{
    int a = 9;
    struct Teacher{
        char name[20];
        int age;
    };
    struct Student{
        char name[20];
        int age;
    };
    
}

namespace NSP_B{
    int a = 12;
    //命名空間嵌套
    namespace NSP_C{
        int c = 90;     
    }
}

  1. 使用命名空間
cout << NSP_A::a << endl;
cout << NSP_B::a << endl;
cout << NSP_B::NSP_C::c << endl;
//使用命名空間中的結(jié)構(gòu)體
using NSP_A::Student;
Student t;
t.age = 90;

::為訪問(wèn)修飾符

二、引用

引用是變量的別名(內(nèi)存空間0x00001的別名),指針是變量的地址

int a = 10;
// b是內(nèi)存空間的另一個(gè)別名
//& C++中的引用
int &b = a;
  1. 使用指針交換數(shù)據(jù)
void swap(int *a, int *b){
    int c = 0;
    c = *a;
    *a = *b;
    *b = c;
}
  1. 使用引用交換數(shù)據(jù)
void swap(int &a, int &b){
    int c = 0;
    c = a;
    a = b;
    b = c;
}

引用的主要功能:作為函數(shù)的參數(shù)或返回值,引用必須有值,不能為空
單純給變量取別名沒(méi)有任何意義,作為參數(shù)傳遞,能保證參數(shù)傳遞過(guò)程中不產(chǎn)生副本;
引用可以直接操作變量,指針要通過(guò)取值(*p),間接操作變量,指針的可讀性差。

  1. 指針的引用代替二級(jí)指針
struct Teacher{
    char* name;
    int age;
};

void getTeacher(Teacher **p){
    Teacher *tmp = (Teacher*)malloc(sizeof(Teacher));
    tmp->age = 20;
    *p = tmp;
}

//代替二級(jí)指針
//Teacher* &p = (Teacher * *p)
void getTeacher(Teacher* &p){
    p = (Teacher*)malloc(sizeof(Teacher));
    p->age = 20;
}
  1. 指針常量/常量指針

指針常量:不改變地址的指針,但是可以修改指針指向的內(nèi)容

int a = 2, b = 3;
int *const p = &a;
p = &b; //不能重新賦值
*p = 4; 可以改變指向的內(nèi)容

常量指針:指向常量的指針,內(nèi)容不能修改

const int *p = &a;
p = &b;
//*p2 = 9;  //不能改變內(nèi)容

三、函數(shù)

  1. C++中函數(shù)可以有默認(rèn)值
void customPrint(int x, int y = 9, int z = 8){
    cout << x << endl;
}
  1. 可變參數(shù)
#include <stdarg.h>
void func(int i,...){
    // 可變參數(shù)指針
    va_list args_p;
    // 開(kāi)始讀取可變參數(shù)類(lèi)型,i是最后一個(gè)固定參數(shù)
    va_start(args_p,i);
    int a = va_arg(args_p,int);
    char b = va_arg(args_p, char);
    int c = va_arg(args_p, int);
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;

    va_end(args_p);
}

void func(int i,...){
    va_list args_p;
    va_start(args_p,i);
    int value;
    // 可變參數(shù)必須是相同類(lèi)型
    while (1) {
    value = va_arg(args_p,int);
    if (value <= 0){
        break;
    }
     cout << value << endl;
    }
    va_end(args_p);
}

四、類(lèi)

  1. 定義頭文件
#pragma once
class Person{
public:
    int age;
    char* name;
public:
    void setAge(int age);
    int getAge();
    void setName(char* name);
    char* getName();
};
  1. 實(shí)現(xiàn)頭文件定義的函數(shù)
#include "Person.h"

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

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

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

char* Person::getName(){
    return this->name;
}
  1. 使用類(lèi)
#include "Person.h"
void main(){
  Person person;
  person.name= "Jack";
}
  1. 構(gòu)造函數(shù)
class Person{
private:
    char *name;
    int age;
public:
    //無(wú)參改造函數(shù)(會(huì)覆蓋默認(rèn)的無(wú)參構(gòu)造函數(shù))
    Person(){
        cout << "無(wú)參構(gòu)造函數(shù)" << endl;
    }
    // 有參構(gòu)造
    Person(char *name, int age){
        this->name = name;
        this->age = age;
        cout << "有參構(gòu)造函數(shù)" << endl;
    }   
  
};

  1. 析構(gòu)函數(shù)

當(dāng)對(duì)象要被系統(tǒng)釋放時(shí)析構(gòu)函數(shù)會(huì)被調(diào)用

~Person(){
    cout << "析構(gòu)函數(shù)" << endl;
    //釋放內(nèi)存
    free(this->name);
}
  1. 拷貝構(gòu)造函數(shù)
class Person{
private:
    char *name;
    int age;
public:
    Person(char *name, int age){
        this->name = name;
        this->age = age;
        cout << "有參構(gòu)造函數(shù)" << endl;
    }
    //拷貝構(gòu)造函數(shù)
    //默認(rèn)的拷貝構(gòu)造函數(shù)是值拷貝,拷貝的是指針地址
    Person(const Person &obj){
        this->name = obj.name;
        this->age = obj.age;
        cout << "拷貝構(gòu)造函數(shù)" << endl;
    }
};
void main(){
  Person p1("Jack",20);
  Person p2 = p1;
}

輸出結(jié)果:

有參構(gòu)造函數(shù)
拷貝構(gòu)造函數(shù)

  1. 深拷貝
    覆蓋默認(rèn)的拷貝構(gòu)造函數(shù),拷貝的是指針指向的內(nèi)容
 Person(const Person &obj){
    //復(fù)制name屬性
    int len = strlen(obj.name);
    this->name = (char*)malloc(len+1);
    strcpy(this->name,obj.name);
    this->age = obj.age;
}

拷貝構(gòu)造函數(shù)被調(diào)用的場(chǎng)景:

  • 聲明時(shí)復(fù)制
  • 最為參數(shù)傳入,實(shí)參給形參賦值
  • 作為函數(shù)返回值返回,給變量初始化賦值
  1. 構(gòu)造函數(shù)的屬性初始化列表
class Teacher{
private:
    char* name;
public:
    Teacher(char* name){
        this->name = name;
    }
    ~Teacher(){
        cout << "析構(gòu)函數(shù)" << endl;
    }
    char* getName(){
        return this->name;
    }

};

class Student{
private:
    int id;
    //屬性對(duì)象
    //Teacher t = Teacher("name");
    Teacher t1;
    Teacher t2;
public:
    Student(int id,char *t1_n, char* t2_n) : t1(t1_n), t2(t2_n){
        this->id = id;
        cout << "Student構(gòu)造函數(shù)" << endl;
    }
    ~Student(){
        cout << "Student析構(gòu)函數(shù)" << endl;
    }
};

五、new/delete動(dòng)態(tài)內(nèi)存分配

void func(){
    //C++   
    //會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
    Teacher *t1 = new Teacher("jack");
    cout << t1->getName() << endl;
    //釋放
    delete t1;

    //C的寫(xiě)法,不會(huì)調(diào)用構(gòu)造函數(shù)和析構(gòu)函數(shù)
    //Teacher *t2 = (Teacher*)malloc(sizeof(Teacher));
    //t2->setName("jack");
    //free(t2);
}

數(shù)組類(lèi)型

//C
//int *p1 = (int*)malloc(sizeof(int) * 10);
//p1[0] = 9;
//free(p1);
    
//C++
int *p2 = new int[10];
p2[0] = 2;
//釋放數(shù)組要加上 []
delete[] p2;

六、靜態(tài)屬性、靜態(tài)方法

class Teacher{
public:
    char* name;
    //靜態(tài)成員
    static int total;
public:
    Teacher(char* name){
        this->name = name;      
        cout << "Teacher構(gòu)造函數(shù)" << endl;
    }
}

靜態(tài)屬性初始化賦值

int Teacher::total = 9;

初始化完成后使用

Teacher::total++;

靜態(tài)函數(shù)

static void count(){
    total++;        
    cout << total << endl;
 }

調(diào)用靜態(tài)函數(shù)

Teacher::count();

七、類(lèi)的大小

class A{
public:
    int i;
    int j;
    int k;
};

class B{
public:
    int i;
    int j;
    int k;
    void fun(){
        cout << "fun" << endl;
    }
};

int main(int argc, const char * argv[]) {
    cout<< sizeof(A)<<endl;
    cout<< sizeof(B)<<endl;
    return 0;
}

輸出結(jié)果:

12
12

C/C++內(nèi)存分區(qū):棧、堆、全局(靜態(tài))、常量去(字符串)、程序代碼區(qū)
普通屬性與結(jié)構(gòu)體相同的內(nèi)存布局
靜態(tài)變量存儲(chǔ)在全局區(qū)
函數(shù)存在程序代碼區(qū)

八、友元函數(shù)

class A{
    //友元函數(shù)
    friend void modify_i(A *p, int a);
private:
    int i;
public:
    A(int i){
        this->i = i;
    }
};

//友元函數(shù)的實(shí)現(xiàn),在友元函數(shù)中可以訪問(wèn)私有的屬性
void modify_i(A *p, int a){
    p->i = a;
}

九、友元類(lèi)

class A{
    //友元類(lèi)
    friend class B;
private:
    int i;
public:
    A(int i){
        this->i = i;
    }

};

class B{
public:
    //友元類(lèi)可以訪問(wèn)A中的任何成員
    void accessAny(){
        a.i = 30;
    }
private:
    A a;
};

十、運(yùn)算符重載

class Point{
public:
    int x;
    int y;
public:
    Point(int x = 0, int y = 0){
        this->x = x;
        this->y = y;
    }
    void myprint(){
        cout << x << "," << y << endl;
    }
    //成員函數(shù)運(yùn)算符重載
    Point operator+(Point &p2){
        Point tmp(this->x + p2.x, this->y + p2.y);
        return tmp;
    }
};

//重載+運(yùn)算符
Point operator+(Point &p1, Point &p2){
    Point tmp(p1.x + p2.x, p1.y + p2.y);
    return tmp;
}

//重載-運(yùn)算符
Point operator-(Point &p1, Point &p2){
    Point tmp(p1.x - p2.x, p1.y - p2.y);
    return tmp;
}

十一、繼承

class Human{
public:
    void say(){
        cout << "say" << endl;
    }
protected:
    char* name;
    int age;
};

//子類(lèi)
class Man : public Human{
public:
    void work(){
        cout << "work" << endl;
    }
private:
    char* brother;
};
int main(int argc, const char * argv[]) {
    Man man;
    man.say();
    Human *p = &man;
    p->say();    
    return 0;
}

帶有參構(gòu)造函數(shù)的繼承

class Human{
public:
    Human(char* name, int age){
        this->name = name;
        this->age = age;
    }
    void say(){
        cout << "say" << endl;
    }
protected:
    char* name;
    int age;
};

class Man : public Human{
public:

    Man(char *brother, char *s_name, int s_age, char *h_name, int h_age) : Human(s_name, s_age), h(h_name,h_age){
        this->brother = brother;
    }
    void work(){
        cout << "work" << endl;
    }
private:
    char* brother;
    Human h;
};

多繼承

//人
class Person{
    
};

//公民
class Citizen{
    
};

//多繼承
class Student : public Person, public Citizen{
    
};

十二、多態(tài)

  1. 虛函數(shù)實(shí)現(xiàn)多態(tài)
//Plane.h
class Plane{
public:
    virtual void fly();
    virtual void land();
};
//Plane.cpp
void Plane::fly(){
    cout << "起飛" << endl;
}

void Plane::land(){
    cout << "著陸" << endl;
}
// Helicopter.h
class Helicopter : public Plane{
    virtual void fly();
    virtual void land();
};
// Helicopter.cpp
void Jet::fly(){
    cout << "直升機(jī)起飛" << endl;
}

void Jet::land(){
    cout << "直升機(jī)著陸" << endl;
}
  1. 純虛函數(shù)(抽象類(lèi))
    當(dāng)一個(gè)類(lèi)具有純虛函數(shù)時(shí),這個(gè)類(lèi)就是抽象類(lèi)。抽象類(lèi)不能實(shí)例化對(duì)象。子類(lèi)繼承抽象類(lèi)必須實(shí)現(xiàn)純虛函數(shù),如果沒(méi)有子類(lèi)也是抽象類(lèi)
class Shape{
public:
    //純虛函數(shù)
    virtual void sayArea() = 0;
};

class Circle : public Shape{
public:
    Circle(int r){
        this->r = r;
    }
    void sayArea(){
        cout << "圓的面積" << (3.14 * r * r) << endl;
    }
private:
    int r;
};

十三、模板函數(shù)(泛型)

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

void myswap(char& a, char& b){
    char tmp = 0;
    tmp = a;
    a = b;
    b = tmp;
}

上面兩個(gè)函數(shù)業(yè)務(wù)邏輯一樣,數(shù)據(jù)類(lèi)型不一樣。

template <typename T>
void myswap(T& a, T& b){
    T tmp = 0;
    tmp = a;
    a = b;
    b = tmp;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容