1. gzyueqian
      13352868059

      粵嵌嵌入式課程老師解析,一個空的類里面有什么

      更新時間: 2018-01-03 14:51:47來源: 粵嵌教育瀏覽量:3125

        粵嵌嵌入式課程老師解析,你知道一個空的類里面是什么嗎?雖然這篇文章的標題,看起來是有點找抽——既然一個類是空的,那不就是說里面啥也沒有嘛? 比如這樣:

        class empty

        { };

        上面定義了一個真的很空的空類,一對大括號里面除了空氣之外,真的什么都沒有!根據C++的語法,這樣的類是可以通過編譯的,并且可以跟別的小朋友一樣到處玩耍、奔跑和嬉鬧。look:

        empty e1;       // e1:“我很空虛!”

        empty e2(e1); // e2:“我跟你一樣空虛!”

        empty e3 = e1; // e3:“我也是!我也是!”

        既然它能干這么多事情,說明這個“空”,是內含玄機的。

        分割線

        仔細觀察上面三條語句,會發(fā)現如下事實:創(chuàng)建e1說明類empty中必然有無參構造函數,創(chuàng)建e2說明類中必然有復制構造函數,創(chuàng)建e3說明類中必然有賦值操作符函數,當然我們還知道任何對象在釋放內存時都會調用析構函數,因此毫無懸念類empty也必然有析構函數。

        綜上所述,你自認為內部只有空氣的類empty,實際上是這個樣子的:

        class empty

        {

        public:

        empty();  // 無參構造函數

        empty(const empty &rh); // 復制構造函數

        ~empty(); // 析構函數

        empty & operator=(const empty &rg); // 賦值操作符函數

        };

        注:如果類empty繼承了虛基類,那么析構函數也將會自動被定義為虛函數。

        原來!C++編譯器會為我們做這么多事情!

        分割線

        但,凡事皆有例外,以上那些不請自來的函數們,是不是任何時候都會出現呢?可不一定。請看精心設計的類node:

        class node

        {

        public:

        node(string &n, const int &a); // 顯式構造函數

        private:

        string &name;

        const int age;

        };

        node::node(string &n, const int &a)

        : name(n), age(a)

        { }

        首先,由于你提供了顯式的構造函數,因此系統(tǒng)將拒絕生成默認的無參構造函數。

        其次,注意到類node中包含引用成員name,以及非靜態(tài)的const型成員age,他們之中的任一個,都會導致系統(tǒng)拒絕生成默認的賦值操作符函數。

        想象一下,此時如果定義兩個node的對象x1和x2,再讓它們之間相互賦值會怎樣?

        string s1("aa"), s2("bb");

        node x1(s1, 100), x2(s2, 200);

        x1 = x2;

        由于x1.name是引用,該引用指向了字符串s1(說白了就是x1.name就是s1的別名),那么 x1 = x2 會讓 x1.name 指向 s2 嗎? 從C++基本語法得知這不可能!因為引用一旦指定了關聯的目標就再也不能修改。那么, x1 = x2 會讓 x1.name指向的s1的值變?yōu)?bb"嗎? 這么一來,那其他跟x1無關的但使用了字符串s1的對象豈不是要平白無故地遭受牽連?

        以上分析,針對類的非靜態(tài)const型成員age而言,是一模一樣的,因為age也不應該通過類對象的賦值操作而發(fā)生改變。

        因此,在上述情形下,默認的賦值操作符函數將不復存在,如果你非要為node提供賦值操作,你必須自己顯式地定義 operator=(),否則編譯器將會在上述代碼的 x1 = x2 這一行報錯。

        事實上,還有一種情形會導致系統(tǒng)拒絕生成默認賦值操作符函數,那就是當類node的基類定義了private的賦值操作符函數。這是因為,當要賦值node對象時,必須先調用基類的賦值操作符,而private的權限設定使這一想法立即破滅。

        總而言之,以下情形發(fā)生時系統(tǒng)將拒絕生成默認賦值操作函數:

        類中含有引用成員

        類中含有非靜態(tài)const型成員

        類繼承自含有private賦值操作符函數的基類

        詭異的是,即便在上述條件下,系統(tǒng)依然會贊同生成默認的拷貝構造函數,即以下代碼仍然是合法的:

        string s1("aa");

        node x1(s1, 100);

        node x2(x1);

        此時,x2和x1內的兩個引用name都指向了s1,他們中的任意一個發(fā)生了變化都將對s1產生影響。消除這樣的副作用的辦法是,自己定義一個復制構造函數來達成恰當的邏輯。想了解更多嵌入式課程的知識,請點擊在線咨詢,或者來粵嵌嵌入式培訓看一看哦!





      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 最新2021久久精品 | 亚洲国产欧美在线看片国产 | 中文字幕亚洲第一 | 日本一本亚洲观看区 | 中文字幕国产综合 | 三级国产片在线观看 |