自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

寫了這么久C++,你的引用成員用對(duì)了嗎?

開發(fā)
你可能會(huì)問(wèn):"真的可以在類里放引用嗎?" 當(dāng)然可以啦!這就像是給類一個(gè)永遠(yuǎn)忠實(shí)的小跟班,一旦確定關(guān)系,就會(huì)一直跟著你到天涯海角!

嗨!小伙伴們,今天我們來(lái)聊一個(gè)有趣的話題 - C++類里的引用成員!你可能會(huì)問(wèn):"真的可以在類里放引用嗎?" 當(dāng)然可以啦!這就像是給類一個(gè)永遠(yuǎn)忠實(shí)的小跟班,一旦確定關(guān)系,就會(huì)一直跟著你到天涯海角!

基礎(chǔ)示例

想象一下,你養(yǎng)了一只超級(jí)黏人的小貓咪 ??,它總是寸步不離地跟著你轉(zhuǎn)悠。這種形影不離的關(guān)系,在C++中用引用成員來(lái)表達(dá)再合適不過(guò)啦!就像是給小貓咪和主人之間系上了一根永遠(yuǎn)都解不開的紅線 ??

class Person {
    string name;
public:
    Person(string n) : name(n) {}
    string getName() { return name; }
};

瞧瞧我們的小貓咪類 ??,它有個(gè)特別之處 - 通過(guò)引用成員owner永遠(yuǎn)記住了它的主人是誰(shuí):

class Cat {
    string name;
    Person& owner;  // 這個(gè)引用就像是小貓咪的定位器,永遠(yuǎn)指向主人 ??
public:
    // 用初始化列表給小貓咪"認(rèn)主" ??
    Cat(string n, Person& p) : name(n), owner(p) {}
    
    void followOwner() {
        cout << name << " 正在屁顛屁顛地跟著 " << owner.getName() << " 呢~ ??" << endl;
    }
};

要記住哦,引用成員就像是出生就定下的緣分,一旦在構(gòu)造時(shí)確定了,就再也改變不了啦!所以在初始化的時(shí)候一定要用初始化列表,就像是在小貓咪"出生證明"上蓋章一樣重要呢!

來(lái)試試看吧!

讓我們一起來(lái)看看這段可愛的代碼是怎么運(yùn)作的:

int main() {
    // 首先我們需要一位溫柔的主人 ??
    Person alice("Alice");
    
    // 然后來(lái)只黏人的小貓咪,從此形影不離~ ??
    Cat kitty("Kitty", alice);
    
    // 瞧瞧!小貓咪馬上就跟著主人到處溜達(dá)啦 ??
    kitty.followOwner();  // 輸出:Kitty正在屁顛屁顛地跟著Alice呢~ ??
}

就是這么簡(jiǎn)單!就像魔法一樣,通過(guò)引用的力量,我們的小貓咪從此就和主人綁定在一起啦!這就是C++引用成員的魅力所在 - 簡(jiǎn)單、直接,還特別有愛。記住哦,這種深厚的"貓主情"一旦建立,就像真正的愛情一樣,天長(zhǎng)地久,永不分離!

重要注意事項(xiàng)

使用引用成員時(shí)要注意這幾點(diǎn)(我們把嚴(yán)肅的規(guī)則說(shuō)得輕松一點(diǎn)):

  • 就像小貓出生必須有主人一樣,引用成員必須在"出生"(構(gòu)造)時(shí)就被初始化。所以默認(rèn)構(gòu)造函數(shù)是不行的!
  • 引用成員的初始化必須在構(gòu)造函數(shù)的初始化列表中完成,不能在構(gòu)造函數(shù)體內(nèi)進(jìn)行。就像這樣:
Cat(string n, Person& p) 
    : name(n), owner(p)  // ? 正確的方式
{ 
    // owner = p;  ? 在這里初始化引用成員是不行的!
}

為什么一定要在初始化列表中初始化引用成員呢?這是因?yàn)椋?/p>

  • 引用一旦聲明就必須立即初始化,不能先聲明后賦值。這是C++語(yǔ)言的基本規(guī)則,引用必須在聲明時(shí)就綁定到一個(gè)對(duì)象。
  • 當(dāng)進(jìn)入構(gòu)造函數(shù)體之前,所有成員變量都已經(jīng)完成構(gòu)造。這意味著在構(gòu)造函數(shù)體內(nèi)進(jìn)行的任何賦值操作都不是初始化,而是對(duì)已經(jīng)初始化的對(duì)象進(jìn)行修改。
  • 在構(gòu)造函數(shù)體內(nèi)的賦值操作實(shí)際上是在試圖改變引用所指向的對(duì)象,而不是在進(jìn)行初始化。然而,引用一旦綁定到一個(gè)對(duì)象,就不能再改變其綁定關(guān)系。
  • 這就像小貓咪必須在"出生"時(shí)就認(rèn)定主人,而不是先生出來(lái),再?zèng)Q定跟誰(shuí)走。引用的這種特性確保了對(duì)象間的關(guān)系在對(duì)象生命周期內(nèi)保持不變。

記?。阂贸蓡T特別適合表達(dá)"永久關(guān)聯(lián)"的關(guān)系,比如我們例子中的貓和主人。但要謹(jǐn)慎使用,因?yàn)檫@種關(guān)系一旦建立就不能改變啦!

初始化列表

嘿!讓我們來(lái)聊聊初始化列表這個(gè)有趣的話題吧!想象一下,如果你是一位魔法師,你有兩種方式來(lái)召喚你的寵物:

  • 第一種是直接用魔法讓它瞬間出現(xiàn)(這就像初始化列表)??,"啪"的一下,你的小伙伴就活靈活現(xiàn)地站在你面前啦!
  • 第二種方式嘛,就像是先召喚出一個(gè)"空殼",然后再往里面注入生命力(這就像在構(gòu)造函數(shù)體內(nèi)賦值)。顯然,第一種方式更簡(jiǎn)單直接,對(duì)不對(duì)?

以下是一個(gè)簡(jiǎn)單的例子,展示了初始化列表和構(gòu)造函數(shù)體內(nèi)賦值的區(qū)別:

class Example {
    int value;
public:
    // 使用初始化列表
    Example(int v) : value(v) {
        // 這里不需要再賦值
    }

    // 在構(gòu)造函數(shù)體內(nèi)賦值
    Example(int v) {
        value = v;  // 先默認(rèn)構(gòu)造,再賦值
    }
};

在上面的例子中,使用初始化列表的方式更高效,因?yàn)樗苊饬瞬槐匾哪J(rèn)構(gòu)造和賦值操作。

所以啊,使用初始化列表不僅僅是為了遵守規(guī)則,它還能讓我們的程序跑得更快呢!就像是坐上了特快列車,"嗖"的一下就到站了!這對(duì)于引用成員來(lái)說(shuō)尤其重要,因?yàn)樗鼈兙拖袷呛π叩男∨笥?,一定要?出生"的那一刻就認(rèn)定好自己的好朋友 

至于普通的成員變量嘛,雖然它們沒那么害羞,可以在"出生"后再交朋友,但是!如果能一開始就交到好朋友,何樂而不為呢?這樣不僅能讓我們的程序跑得更快,還能避免一些不必要的麻煩,就像是省去了"相親"的過(guò)程,直接就找到了真愛一樣!

記住哦,在C++的世界里,初始化列表就像是一個(gè)溫暖的魔法口袋,能讓我們的對(duì)象們快速又開心地誕生!讓我們一起用這個(gè)小魔法,創(chuàng)造出更多精彩的程序吧!

  • 初始化列表的優(yōu)勢(shì):使用初始化列表不僅是語(yǔ)法上的要求,對(duì)于引用成員來(lái)說(shuō),它還可以提高性能。因?yàn)樵诔跏蓟斜碇校蓡T變量是直接構(gòu)造的,而不是先默認(rèn)構(gòu)造再賦值。
  • 普通成員變量的初始化:普通成員變量可以在初始化列表中初始化,也可以在構(gòu)造函數(shù)體內(nèi)賦值。然而,使用初始化列表通常是更好的選擇,尤其是對(duì)于類類型的成員,因?yàn)樗苊饬瞬槐匾哪J(rèn)構(gòu)造和賦值操作。

通過(guò)這些補(bǔ)充,我們可以更好地理解為什么引用成員必須在初始化列表中初始化,以及這種方式的優(yōu)勢(shì)所在。希望這些信息能幫助你更深入地理解C++中的引用成員!

什么是"直接構(gòu)造"?

讓我們用一個(gè)生動(dòng)的例子來(lái)理解什么是"直接構(gòu)造"以及它為什么更高效!

想象你在玩積木游戲,你有兩種方式來(lái)建造你想要的東西:

  • 直接構(gòu)造:直接用積木搭建成你想要的形狀
  • 先默認(rèn)構(gòu)造再賦值:先隨便搭個(gè)樣子,然后再拆掉重建

來(lái)看個(gè)具體的例子:

class MyClass {
    int value;
public:
    // 構(gòu)造函數(shù)
    MyClass(int v) : value(v) { }  // 直接構(gòu)造
    
    // 默認(rèn)構(gòu)造函數(shù)
    MyClass() : value(0) { }
    
    // 賦值操作符
    MyClass& operator=(int v) {
        value = v;
        return *this;
    }
};

class Container {
    MyClass obj;
public:
    // 方式1:直接構(gòu)造 - 只調(diào)用一次構(gòu)造函數(shù)
    Container(int x) : obj(x) { }  // ? 更高效
    
    // 方式2:先默認(rèn)構(gòu)造,再賦值 - 調(diào)用默認(rèn)構(gòu)造函數(shù)后還要調(diào)用賦值操作符
    Container(int x) {
        obj = x;  // ? 效率較低
    }
};

兩種方式的區(qū)別:

(1) 直接構(gòu)造(使用初始化列表):

  • 就像直接把積木搭建成想要的形狀
  • 只執(zhí)行一次構(gòu)造操作
  • 內(nèi)存中直接創(chuàng)建目標(biāo)值

(2) 先默認(rèn)構(gòu)造再賦值:

  • 像是先搭個(gè)空房子,再進(jìn)行裝修
  • 先調(diào)用默認(rèn)構(gòu)造函數(shù)(創(chuàng)建值為0的對(duì)象)
  • 然后再調(diào)用賦值操作符(修改為目標(biāo)值)
  • 執(zhí)行了兩次操作,效率較低

所以說(shuō),直接構(gòu)造就是"一步到位"地創(chuàng)建對(duì)象,避免了不必要的中間步驟。特別是對(duì)于引用成員這種必須立即初始化的情況,使用初始化列表進(jìn)行直接構(gòu)造是唯一的選擇!

使用建議

引用成員最適合表達(dá)對(duì)象之間的固定關(guān)聯(lián)關(guān)系。在使用時(shí)要考慮:

  • 被引用對(duì)象的生命周期必須長(zhǎng)于包含引用的對(duì)象
  • 確保關(guān)聯(lián)關(guān)系確實(shí)需要是永久的
責(zé)任編輯:趙寧寧 來(lái)源: everystep
相關(guān)推薦

2020-12-07 11:05:21

HttpClient代碼Java

2020-02-15 15:33:55

Python如何運(yùn)作

2022-08-21 14:00:11

消息中間件MQ

2021-07-21 10:10:14

require前端代碼

2021-11-08 10:00:19

require前端模塊

2022-01-25 12:41:31

ChromeResponse接口

2024-12-17 15:00:00

字符串Java

2022-02-08 13:39:35

LinuxUNIX系統(tǒng)

2018-06-08 10:12:10

Web緩存體系服務(wù)器

2019-12-04 12:33:48

程序員技術(shù)設(shè)計(jì)

2021-05-28 06:16:28

藍(lán)牙Wi-FiNFC

2021-05-27 21:18:56

谷歌Fuchsia OS操作系統(tǒng)

2021-04-28 11:35:06

Java框架日志

2020-12-01 10:18:16

RabbitMQ

2024-02-23 09:36:57

C#工具并行處理

2017-03-21 13:53:17

運(yùn)維戴爾企業(yè)級(jí)解決方案

2020-03-30 09:22:03

AI語(yǔ)音技術(shù)機(jī)器視覺

2024-09-18 10:08:37

2022-05-09 07:27:50

ThreadLocaJava
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)