c++之類中複雜關係!!

第一種:友元

友元函數

當我們有這麼一種需求:一個函數參數爲類時,這就需要訪問類的內部成員,public成員可以訪問,那當我們需要訪問private成員的時候呢?這在c++中如何實現呢?就需要通過友元函數了!

舉例:

class T
{
    friend void Hp_Add(T& t1); //友元函數聲明,此函數就可以訪問private成員了
private:
    int Hp;   //私有成員,無法從外部直接訪問

public:
    void Set_Hp(int _Hp) {
        Hp = _Hp;
    }
    int Get_Hp() const{
        return Hp;
    }
    
};

void Hp_Add(T& t1)
{
    t1.Hp++;//對私有成員進行寫操作
}

int main()
{
    T t1; t1.Set_Hp(10);
    Hp_Add(t1);
    cout << t1.Get_Hp();
}

來看一下結果:
在這裏插入圖片描述
總結: 這裏就通過聲明友元函數的方式來進行對類中private成員進行訪問了!

友元類

當我們出現如下需求時:第二個類中的某些成員函數需要訪問第一個類中的私有成員變量,這時候就可以通過友元類的方式進行實現!

舉例如下:

class T1
{
    friend class T2; //聲明一個友元類!
private:
    int Hp;

public:
    void Set_Hp(int _Hp) {
        Hp = _Hp;
    }
    int Get_Hp() const{
        return Hp;
    }
    
};

class T2
{
private:
    int Mp;
public:
    void T1Hp_Add(T1&t) {  //這個類想要修改T1類中private成員
        t.Hp++;
    }
};

int main()
{
    T1 t1; t1.Set_Hp(10);  //給Hp賦值10
    T2 t2; t2.T1Hp_Add(t1); //通過T2類來改變t1的Hp
    cout <<"t1的Hp爲 " <<t1.Get_Hp() << endl;
}

來看一下結果:
在這裏插入圖片描述
這裏注意: 友元類的朋友關係只是單方面的,就如同上面的例子,T1類說T2是我的朋友,這時候T2類中就可以訪問T1類的私有成員。但是反之則不成立,T1就無法訪問T2的私有成員!

友元之總結:

1、友元類不是對等關係

2、友元類會破壞類的封裝性,除非迫不得已,否則不要用!

第二種:嵌套類

舉個例子:我們人這個類有身高、體重,也有鞋子這個屬性。鞋子又有大小、品牌、顏色屬性。這時候是不是很符合類的嵌套呢?Yes,這時候就可以用類的嵌套來設計類了!

這裏舉個簡單的小案例,代碼如下:


enum class Shoe_Color  //自定義鞋子顏色類型
{
    red = 1,
    blue,
    green,
};
enum class Shoe_Brand //自定義鞋子品牌類型
{
    Nike = 1,
    Adidas,
    Anta,
};
class Person //外層類,人
{
public:
    short height;//身高
    short weight;//體重
    class Shoes;     //鞋子  嵌套類的聲明,寫成這樣時爲了類的整潔性
};
//嵌套類詳細的聲明
class Person::Shoes 
{
private:
    short Size;
    enum Shoe_Color Color;
    enum Shoe_Brand Brand;
public:
    void Show();
    void Init_Shoes(short _Size, enum Shoe_Color _Cor, enum Shoe_Brand _Bra);
};
//嵌套類成員函數的實現,分文件寫也是一樣的
void Person::Shoes::Init_Shoes(short _Size, enum Shoe_Color _Cor, enum Shoe_Brand _Bra)
{
    Size = _Size;
    Color = _Cor;
    Brand = _Bra;
}
//嵌套類成員函數的實現
void Person::Shoes::Show()
{
    string Brand{}, Cor{};
    switch ((int)this->Brand) {
	    case (int)Shoe_Brand::Nike:
	        Brand = "Nake";
	        break;
	    case (int)Shoe_Brand::Adidas:
	        Brand = "Adidas";
	        break;
	    case (int)Shoe_Brand::Anta:
	        Brand = "Anta";
	        break;
    }
    switch ((int)this->Color) {
	    case (int)Shoe_Color::red:
	        Cor = "紅色";
	        break;
	    case (int)Shoe_Color::green:
	        Cor = "綠色";
	        break;
	    case (int)Shoe_Color::blue:
	        Cor = "藍色";
	        break;
    }
    cout << "碼數:" << Size << " 品牌: " << Brand << " 顏色:" << Cor << endl;
}
int main()
{
    Person::Shoes shoe; //定義一雙鞋得通過人的類加::限定符
    shoe.Init_Shoes(40,Shoe_Color::red,Shoe_Brand::Nike);
    shoe.Show();
}

來看一下結果:
在這裏插入圖片描述
最後來說一下嵌套類中嵌套類和外層類訪問權限的關係:

1、嵌套類可調用外層類所有成員

2、外層類僅能訪問嵌套類中的共有成員

第三種:局部類

什麼叫局部類呢?定義在函數內的類稱爲局部類!

雖然比較少見,但是也爲了自己留個印象還是簡單的學習一下!

差不多總結有三條規定:
1、局部類中不允許使用靜態成員變量

有圖有真相:
在這裏插入圖片描述
2、局部類定義必須在類內

有圖有真相:
在這裏插入圖片描述
3、局部類可以訪問全局變量


int flag = 10; //定義一個全局變量
void Func()
{
    class T   //定義局部類
    {
    private:
        int hp;
        int mp;
    public:
        void Init()
        {
            ::flag++;  //令全局變量加1
            hp = 1000;
            mp = 500;
        }
    };
    T t1;   //實例化一個局部類
    t1.Init();  //令flag++,看看是不是加1了
}


int main()
{
    cout << "flag=" << ::flag << endl;
    Func();
    cout << "flag=" << ::flag << endl;

結果:
在這裏插入圖片描述
這裏我們看到局部類時能夠調用全局變量的!!!!

感謝自己努力拼搏的學習!!!老鐵們覺得有點用的話,記得點點贊哦!!!我是航行的小土豆!!!
在這裏插入圖片描述

發佈了21 篇原創文章 · 獲贊 20 · 訪問量 2380
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章