1. 程式人生 > 實用技巧 >C++學習-類2

C++學習-類2

靜態成員

靜態資料成員

關鍵字static,可以實現不同物件之間的資料共享。
組成:類內宣告類外初始化。兩者缺一不可

\\類內宣告 
static 資料型別 名;  
\\類外初始化
資料型別 類名::靜態資料成員名=初始值;
  1. 必須要類內宣告內外初始化,如果內外無初始化會報錯。
    定義類時不會為靜態資料成員分配空間,類外初始化才分配空間
  2. 和其他類內的資料成員一樣,private只能在類內使用,public可以在內外使用
  3. 不屬於物件屬於類,但所有物件都共用。可以通過域操作符直接呼叫 如類名::rate,也可以有可以通過物件引用,如:物件名.rate
  4. 程式開始時產生,結束時消失

補充:靜態常量成員,定義:static const 型別 資料成員名


靜態常量成員後兩種初始化方法,一種是類外,一種是類內。

class AA
{
    private:
        static const int num;
};
const int AA::num=3;
//或者
class AA
{
    private:
        static const int num=3;
};

而靜態資料成員必須是類內宣告,類外初始化。

靜態成員函式

靜態成員函式時為累的全體物件服務,不需要藉助任何物件就可以呼叫,無法處理類中非靜態成員變數,也不允許需用this指標。
類內定義在定義前在static,類內宣告類外定義,只要在宣告前加static,類外定義時不需要加static
呼叫方式:類名::函式名 或 物件.函式名

  • 靜態成員函式不能訪問一幫的資料成員,而只能訪問靜態資料成員或其它靜態成員函式。但如果傳遞該類的物件或物件的引用,或者在函式內創造一個該類的物件,那麼可以使用該物件的所有成員,包括私有(如果不是常物件)。
#include<iostream>
using namespace std;

class AA
{
    private:
        int a;
    public:
    AA(int h=0)
    {
        a=h;
    }
    static void abc(AA &aa)
    {
        aa.a++;
        cout<<aa.a;
    }
};

int main()
{
    AA aa;
    AA::abc(aa);
    return 0;
}

結果輸出1。

友元

友元不是類的成員,當他可以訪問類的任何成員包括私有成員,友元包括友元函式,友元成員函式,友元類。
friend是關鍵字,格式為:

friend 返回型別 函式名(形參表)
{
    函式體;
}

下面依次介紹三種。
友元函式

//在類A中加入
friend void f();//把函式f作為類A的友元,可以類內定義也可以類外定義函式。如果類外定義,類外不需friend。

友元成員函式函式:

B的成員函式:int func(double);
若宣告為類A的友元,在類A定義中加入:
friend int B::func(double);

友元類

//在類A中加入
friend class B;//把整個類B作為類A的友元

友元關係宣告可以放在函式任意一個地方,,可以私有也可以公有,效果不會影響,不過一般放在最前面或最後面。
補充:前向引用宣告,和函式的宣告差不多,可以在後面定義類然後在開頭加上宣告。

#include <iostream>
using namespace std;
class B; //前向引用宣告。
class A{
    public:
        void f(B &b);
    private:
        B *b; // 不能使用 B b
};
class B{
    public:
        void g(A a);
    private:
        A a;
};

但前向引用宣告不是萬能的。
在宣告之前,不能宣告該類的物件,也不能在內聯成員函式中使用該類物件。
前向引用宣告時,只能使用被宣告的符號,不能涉及類的任何細節。

class Fred;
class Braney{
  Fred x; // 錯誤:類Fred的宣告尚不完善。
};
class Fred{
  Braney y;
};

課堂上的筆記補充:

  • 如果自己定義任意一個普通的建構函式,則系統不再提供預設建構函式,但會提供一個預設的拷貝建構函式;如果定義了一個拷貝建構函式,則系統不再提供預設建構函式和預設拷貝建構函式
  • 如果函式的返回值是常量,或傳遞的實參是個常量,或給物件初始化的是一個常量,如Clock(1,2,3);(Clock是類名),則呼叫建構函式而不是拷貝建構函式。