NDK—C++類

上一篇我們學習了C++的命名空間,這篇我們來了解一下C++的構造和析構函數

廢話不多說,開始擼碼

正文

構造函數、析構函數、拷貝構造函數

來個簡單的例子,了解一下構造和析構的寫法

class Teacher{
    public:
        int age;
    public:
        Teacher(){
            cout << "無參構造函數" << endl;
        }
        ~Teacher(){
            cout << "析構函數" << endl;
        }
    };

當類沒有構造函數的時候默認會有一個無參的構造函數,構造函數的作用是初始化變量,析構函數則釋放資源

既然有了構造函數,那怎么創建對象呢?

無參構造:   Teacher t;
有參構造:   Teacher t1("lypop", 21);
            Teacher t2 = Teacher("lypop", 21);
創建指針:   Teacher *tt = new Teacher("lypop",21);

對于析構函數的調用,我們將創建放在一個方法里面,當方法執行結束便會執行析構函數

class Teacher{
private:
    char *name;
    int age;
public:
    Teacher(){
        this->name = (char*)malloc(100);
        strcpy(name, "lypop");
        age = 20;
        cout << "無參構造函數" << endl;
    }
    
    //析構函數
    ~Teacher(){
        cout << "析構" << endl;
        //釋放內存
        free(this->name);
    }
};

void func2(){
    Teacher t;
}

我們只需要在析構函數中釋放相應的資源

除了構造函數和析構函數,類里面有個默認的拷貝構造函數,它只是一種值拷貝,當類中有指針屬性的時候容易發生崩潰。所以當我們類中有指針需要在析構函數釋放資源的時候,拷貝構造函數都使用深拷貝

下面來看一下值拷貝(淺拷貝)

class Teacher{
private:
    char *name;
    int age;
public:
    Teacher(char *name, int age){
        this->name = (char*)malloc(100);
        strcpy(this->name,name);
        this->age = age;
        cout << "有參構造函數" << endl;
    }   
    ~Teacher(){
        cout << "析構" << endl;
        //釋放內存
        free(this->name);
    }
};

void func(){
    Teacher t1("rose", 20);

    Teacher t2 = t1;//這時候會調用默認的拷貝構造函數
}

當func執行完畢之后就會調用兩次析構,因為只是簡單的值拷貝,name指針指向的是同一塊內存地址,當第一個被釋放掉在釋放第二個的時候就會出錯。所以需要解決這種就需要深拷貝,也就是重寫拷貝構造函數為name重新開辟一塊內存地址

//深拷貝
Teacher(const Teacher &obj){
    //復制name屬性
    int len = strlen(obj.name);
    this->name = (char*)malloc(len+1);
    strcpy(this->name,obj.name);
    this->age = obj.age;
}

拷貝構造函數被調用的場景:

  1. 聲明時賦值
  2. 作為參數傳入,實參給形參賦值
  3. 作為函數返回值返回,給變量初始化賦值
C和C++創建指針和釋放資源
C  創建 int *p1 = (int*)malloc(sizeof(int) * 10);
   釋放 free(p1);

C++創建 int *p2 = new int[10];
   釋放 delete[] p2;//釋放數組指針  delete p;//釋放指針
C++訪問靜態屬性和方法

通過類名::來訪問,也可以通過類對象來訪問

int Teacher::total = 9;
Teacher::total++;
Teacher::count();
常量對象、常函數

Teacher *const this;能改變指針指向的內容,不能改變指針的值

const Teacher* const this;既不能改變指針的值,又不能改變指針指向的內容

常量對象只能調用常量函數,不能調用非常量函數。常函數當前對象不能被修改,防止數據成員被非法訪問

class Teacher{
    void myprint() const{
        
    }
};
void main(){
    const Teacher t1("aaa",22);

    t.myprint(); 

    system("pause");

}
友元函數、友元類

友元函數的實現,在友元函數中可以訪問私有的屬性

class A{
friend void modify_i(A *p, int a);
private:
    int i;
};
void modify_i(A *p, int a){
    p->i = a;
}

友元類中可以訪問友元對象所在類的所有成員

class A{
friend class B;
private:
    int i;

};

class B{
public:
    //B這個友元類可以訪問A類的任何成員
    void accessAny(){
        a.i = 30;
    }
private:
    A a;
};
運算符重載
  1. 類外進行運算符重載

     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;
         }
     
     };
     
     Point operator+(Point &p1, Point &p2){
         Point tmp(p1.x+p2.x,p1.y+p2.y);
         return tmp;
     }
     
     Point operator-(Point &p1, Point &p2){
         Point tmp(p1.x - p2.x, p1.y - p2.y);
         return tmp;
     }
    
  2. 類內進行運算符重載

     class Point{
     public:
         int x;
         int y;
     public:
         Point(int x = 0, int y = 0){
             this->x = x;
             this->y = y;
         }
         //成員函數,運算符重載
         Point operator+(Point &p2){
             Point tmp(this->x + p2.x, this->y + p2.y);
             return tmp;
         }
         void myprint(){
             cout << x << "," << y << endl;
         }
         };
    
  3. 當屬性私有的時候需要使用友元函數實現運算符重載

     class Point{
     friend Point operator+(Point &p1, Point &p2);
     private:
         int x;
         int y;
     public:
         Point(int x = 0, int y = 0){
             this->x = x;
             this->y = y;
         }   
         void myprint(){
             cout << x << "," << y << endl;
         }
     };
     
     Point operator+(Point &p1, Point &p2){
         Point tmp(p1.x + p2.x, p1.y + p2.y);
         return tmp;
     }
    

但是運算符重載的本質還是函數的調用,至此C++的類就總結到這里,謝謝不耐其煩的看完。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • /*類和對象 1.類和實例化定義類聲明類定義成員函數數據成員的賦值使用類的對象。 2.構造函數數據封裝默認構造函數...
    aofeilin閱讀 1,086評論 1 2
  • 2.1 類的基礎知識2.2 構造函數2.3 拷貝構造函數2.4 析構函數2.5 C++能自動產生成員函數2...
    笑笑學生閱讀 417評論 0 0
  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile麗語閱讀 3,858評論 0 6
  • 1.面向對象的程序設計思想是什么? 答:把數據結構和對數據結構進行操作的方法封裝形成一個個的對象。 2.什么是類?...
    少帥yangjie閱讀 5,044評論 0 14
  • //出自51博客:www.Amanda0928.51.com 第一章 一、選擇題 1.B; (typedef ,t...
    Damongggggg閱讀 11,196評論 0 1