首頁 >後端開發 >C#.Net教程 >C++學習基礎-this指標、靜態成員、常數成員函數

C++學習基礎-this指標、靜態成員、常數成員函數

php是最好的语言
php是最好的语言原創
2018-08-08 11:29:501993瀏覽

一、this指標

1、C 程式到C程式的翻譯

class CCar {                          struct CCar {
    public:                                int price;
    int price;                        };
    void SetPrice(int p);             void SetPrice(struct CCar * this,int p){
};                                        this->price = p;
void CCar::SetPrice(int p){           }
    price = p; //this->price = p;
}                                     int main() {
int main(){                               struct CCar car;
    CCar car;                             SetPrice( & car,20000);
    car.SetPrice(20000);                  return 0;
    return 0;                         }
}

2、this指標作用:非靜態成員函數中可以直接使用this來代表指向此函數作用的物件的指標

3、this指標與靜態成員函數:靜態成員函數並沒有具體作用與某個對象,所以靜態成員函數中不能使用this 指標

二、靜態成員

  • 靜態成員:在說明前面加了static關鍵字的成員。

  • 普通成員變數每個物件都有各自的一份,而靜態成員變數一共就一份,為所有物件共享,sizeof 運算子不會計算靜態成員變數。

  • 普通成員函數必須具體作用於某個對象,而靜態成員函數並不具體作用於某個對象,不需要透過對象就能存取。

class CRectangle{
    private:
        int w, h;
        static int nTotalArea; // 静态成员变量
    public:
        CRectangle(int w_,int h_);
        ~CRectangle();
        static void PrintTotal(); // 静态成员函数
};

1、存取靜態成員的方法:

  • 類別名稱::成員名稱        CRectangle::PrintTotal();

  • #物件名稱.成員名稱     CRectangle r; r.PrintTotal();

  • 指標->成員名       CRectangle * p = &r; p-> PrintTotal();

  • 引用.成員名         CRectangle & ref = r; int n = ref.nTotalNumber;

2、注意事項:

  • 靜態成員變數本質上是全域變量,即使一個物件都不存在,類別的靜態成員變數也存在

  • 必須在定義類別的檔案中對靜態成員變數進行一次說明或初始化。否則編譯能通過,連結不能透過

  • 在靜態成員函數中,不能存取非靜態成員變量,也不能透過

#三、成員物件與封閉類別

1、定義:有成員物件的類別叫做封閉(enclosing)類別

class CTyre{             // 轮胎类
    private:
        int radius;      // 半径
        int width;       // 宽度
    public:
        CTyre(int r,int w):radius(r),width(w) { }
};
class CEngine{           // 引擎类
};
class CCar {             // 汽车类
    private:
        int price;       // 价格
        CTyre tyre;
        CEngine engine;
    public:
        CCar(int p,int tr,int tw );
};
CCar::CCar(int p,int tr,int w):price(p),tyre(tr, w){};
int main(){
    CCar car(20000,17,225);
    return 0;
}

   上例中,若CCar類別不定義建構函數,則下面的語句會編譯出錯:CCar car;因為編譯器不懂car.tyre該如何初始化。 car.engine 的初始化沒問題,用預設構造函數即可。任何產生封閉類別物件的語句,都要讓編譯器明白,物件中的成員對象,是如何初始化的。具體的做法就是:透過封閉類別的建構函數的初始化列表。

    2、封閉類別建構子和析構函數的執行順序
  • 封閉類別物件產生時,先執行所有物件成員的建構函數,然後才執行封閉類別的建構函數。
  • 物件成員的建構子呼叫次序和物件成員在類別中的說明順序一致,與它們在成員初始化清單中出現的順序無關。
  • 當封閉類別的物件消亡時,先執行封閉類別的析構函數,然後再執行成員物件的析構函數。次序和建構函數的呼叫次序相反。

class CTyre {
    public:
        CTyre() { cout << "CTyre contructor" << endl; }
        ~CTyre() { cout << "CTyre destructor" << endl; }
};
class CEngine {
    public:
        CEngine() { cout << "CEngine contructor" << endl; }
        ~CEngine() { cout << "CEngine destructor" << endl; }
};
class CCar {
    private:
        CEngine engine;
        CTyre tyre;
    public:
        CCar( ) { cout << “CCar contructor” << endl; }
        ~CCar() { cout << "CCar destructor" << endl; }
};
int main(){
    CCar car;
    return 0;
}
//输出结果:
CEngine contructor
CTyre contructor
CCar contructor
CCar destructor
CTyre destructor
CEngine destructor

四、友元(friends)

1、友元分為友元函數和友元類別兩種

#(1)友元函數:  一個類別的友元函數可以存取該類別的私有成員

class CCar ;     //提前声明 CCar 类,以便后面的CDriver 类使用
class CDriver{
    public:
    void ModifyCar( CCar * pCar) ;         // 改装汽车
};
class CCar{
    private:
        int price;
        friend int MostExpensiveCar( CCar cars[], int total); // 声明友元
        friend void CDriver::ModifyCar(CCar * pCar);     // 声明友元,可包括构造、析构函数
};
void CDriver::ModifyCar( CCar * pCar){
    pCar->price += 1000;                        // 汽车改装后价值增加
}
int MostExpensiveCar( CCar cars[],int total){   // 求最贵汽车的价格                           
    int tmpMax = -1;
    for( int i = 0;i < total; ++i )
    if( cars[i].price > tmpMax)
    tmpMax = cars[i].price;
    return tmpMax;
}

(2)友元類別: 如果A 是B的友元類,那麼A 的成員函數可以存取B的私有成員,友元類別之間的關係不能傳遞,不能繼承 

class B{
    friend class A;      // 声明A为友元类
};

五、常數成員函數

    1、作用:如果不希望某個物件的值被改變,則定義該物件的時候可以在前面加const關鍵字
  • 在類別的成員函數說明後面可以加const關鍵字,則該成員函數成為常數成員函數。
  • 常數成員函數內部不能改變屬性的值,也不能呼叫非常量成員函數
  • 在定義常數成員函數和宣告常數成員函數時都應該使用const 關鍵字

class Sample {
    private :
        int value;
    public:
        Sample() { }
        void SetValue() {  }
};
const Sample Obj;  //  常量对象
Obj.SetValue ();   //错误,常量对象只能使用构造函数、析构函数和有const说明的函数(常量方法)

2、常數成員函數的重載:兩個函數,名字和參數表都一樣,但是一個是const,一個不是,算重載

3、mutable成員變數:

(1)作用:mutable突破const的限製而設置,被mutable修飾的變數將永遠處於可變的轉態,即使在一個const函數中。

(2)應用:如果類別的成員函數不會改變物件的狀態,那麼一般會宣告成const。但是,有些時候,需要在const的函式裡面修改一些跟類別狀態無關的資料成員,那麼這些資料成員就應該被mutable來修飾。

class CTest{
    public:
        bool GetData() const{
            m_n1++;
            return m_b2;
        }
    private:
        mutable int m_n1;
        bool m_b2;
};

相關推薦:

C 靜態成員與常成員的使用

C 複習要點總結五靜態成員變數及成員函數######

以上是C++學習基礎-this指標、靜態成員、常數成員函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn