天天看點

c++學習筆記之封裝篇(上)

title: c++學習筆記之封裝篇(上)

date: 2017-03-12 18:59:01

tags: [c++,c,封裝,類]

categories: [學習,程式員,c/c++]

---

一、類對象

假設我們由Tv這個類,定義如下

注意class結尾要加上分号
class Tv()
{
    int width;
    int height;
    int volume;
    void changeVolume()
    {
        //changeVolume
    }
};
           

類的執行個體化有兩種方法,一種是棧中執行個體化。另一種則是堆中執行個體化。

而這兩種方法除了在用法上有差別以外(差別見下面代碼),記憶體管理也有差別(棧不用考慮記憶體回收問題,系統會自動回收,而堆則需要程式員主動釋放記憶體)。

1.執行個體化

  • 從棧中執行個體化對象
Tv tv;

或者 

Tv tv[20]  //執行個體化對象數組     從棧中執行個體化系統自動回收記憶體           
  • 從堆中執行個體化對象

執行個體化一個對象後還需要判斷是否成功申請到記憶體

Tv *p = new Tv();    
Tv *q = new Tv[20];  //開辟一塊對象記憶體  

if(p==NULL)
{
    cout<<"類執行個體化失敗"<<endl;
}

//從堆中執行個體化數組對象,需要程式員回收
delete p;   
delete[]q; 
p = NULL;
q =NULL;           

通路資料

  • 通過棧執行個體化的對象通路資料成員:
tv.volume = 5;   
tv.changeVolume();           
  • 通過堆執行個體化的對象通路資料成員:
tv->volume = 5; 
tv->changeVolume();           

二、string

可以很友善的定義一個字元串,而不再是使用麻煩的char[].

使用方法:

// 引入string頭檔案
#include <string>           

初始化方法

注意:第4個初始化方法中的第二個參數隻能是一個字元,不能是字元串。
c++學習筆記之封裝篇(上)

常用操作

c++學習筆記之封裝篇(上)

對于字元串相加操作,需要注意一點,不能直接使用兩個字元串相加,中間必須得有字元串變量連接配接才行(下面例子中最後一個指派語句是錯誤的),具體例子如下:

c++學習筆記之封裝篇(上)

另外如果要将字元串和整數連在一起輸出,則需要在整數前加上 << 進行處理,直接用 “+” 是無效的。

string name;
cin>>name;
cout<<name<<name.size()<<endl;           

三、構造函數

  • 構造函數必須與類同名,起到的作用與python中的 **_ init > _()** 函數類似,即對類進行資料初始化。
  • 構造函數在對象執行個體化時被自動調用,且隻調用一次。
  • 構造函數沒有傳回值,不需要return值。
  • 構造函數可以重載。

1. 構造函數分為有參與無參

舉個栗子:

class Student
{
    // 無參構造函數
    Student()
    {
        m_iHeight = 180;
        m_iWeight = 70;
    }
    
    // 有參構造函數
    Student(int weight, int height)
    {   
        m_iWeight = weight;
        m_iHeight = height;
    }
    
    private:
        int m_iWeight;
        int m_iHeight;
}           

2. 構造函數初始化清單

在初始化對象時,初始化清單是最先執行的,是以有的時候對于const變量我們也可以提前指派。

文法:

類名():變量1(參數),變量2(參數){}

用法:

我們都知道一個人的身份證資訊一般來說是不能随意篡改的,是以我們會使用const 來修飾,但是因為const修飾後,變量則不能再指派,但是因為每個人的身份證又不一樣,我們不可能在使用const修飾的同時進行指派,那怎麼辦呢?是以這裡用到了初始化清單來達到這麼一個效果,詳見下面的代碼示例:

class Student
{
    // 正确示例
    // 初始化清單
    Student(string id):m_iId(id)
    {
        // 初始化成功
    }
    
    // 編譯會報錯
    // Student(string id)
    // {
    //    m_iId = id;
    // }
    
    private:
      const string m_iId;
}           

初始化類數組

Coordinate *coorArr = new Coordinate[2]{{1,2},{3,4}};           

具體示例

#include <iostream>
using namespace std;
class Coordinate
{
    
    public:
        Coordinate(int x,int y):m_iX(x),m_iY(y)
        {
            cout<<m_iX<<","<<m_iY<<endl;
        }
        // 列印坐标的函數
        void printInfo()  
        {
            cout<<m_iX<<","<<m_iY<<endl;
        }
    private:
        int m_iX;
        int m_iY;
};
int main(void)
{
    //定義對象數組
    Coordinate *coorArr = new Coordinate[2]{{1,2},{3,4}};
    
    
    //周遊數組,列印對象資訊
    for(int i = 0; i < 2; i++)
    {
        coorArr[i].printInfo();
    }   
    return 0;
}           

3. 拷貝構造函數

  • 不能重載

    格式:

    類名(const 類名& 變量名)

關于拷貝構造函數更具體的解析參考:

C++拷貝構造函數詳解

4.析構函數

與構造函數相反,當一個對象的生命周期結束時,C++會自動調用一個特殊的成員函數,即析構函數進行善後工作,對成員變量所占記憶體進行釋放操作。

格式:(不需要參數)

~類名(){}

class Student
{
    // 構造函數,初始化清單
    Student():m_iId(110){};
    // 析構函數,c++可以自動生成
    ~Student(){};
}           

對象的生命曆程:

申請記憶體-->初始化清單-->構造函數-->參與運算-->析構函數-->釋放記憶體

c++學習筆記之封裝篇(上)

MARSGGBO 原創 2017-3-26