C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題

一.臨時(shí)對(duì)象

Q:下面的程序?qū)⑤敵鍪裁??為什么?/strong>

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括句容網(wǎng)站建設(shè)、句容網(wǎng)站制作、句容網(wǎng)頁(yè)制作以及句容網(wǎng)絡(luò)營(yíng)銷(xiāo)策劃等。多年來(lái),我們專(zhuān)注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,句容網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到句容省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

#include <iostream>
using namespace std;
class Test
{
    int mi;
public:
    Test(int i)
    {
        mi=i;
    }
    Test()
    {
        Test(0);
    }
    void print()
    {
        cout<<"mi="<<mi<<endl;
    }
};
int main()
{
    Test t;
    t.print();

    return 0;
}

由上面的程序可以得出,該程序的本意在Test()中以0作為參數(shù)調(diào)用Test(int),t同時(shí)將mi初始值設(shè)置為0,并將其打印出來(lái)
運(yùn)行結(jié)果如圖所示
C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題
由運(yùn)行結(jié)果得知,mi的初始值為隨機(jī)值,從這里得出一個(gè)疑問(wèn),構(gòu)造函數(shù)是一個(gè)特殊的函數(shù),是否可以直接調(diào)用?是否可以在構(gòu)造函數(shù)中調(diào)用構(gòu)造函數(shù)?直接調(diào)用構(gòu)造函數(shù)的行為是什么?
答案--直接調(diào)用構(gòu)造函數(shù)將產(chǎn)生一個(gè)臨時(shí)對(duì)象,臨時(shí)對(duì)象的生命周期只有一條語(yǔ)句的時(shí)間,臨時(shí)對(duì)象的作用域只在一條語(yǔ)句中,臨時(shí)對(duì)象是C++中值得警惕的灰色地帶
解決方法代碼如下

#include <iostream>
using namespace std;
class Test
{
    int mi;
    void init(int i)
    {
        mi=i;
    }
public:
    Test(int i)
    {
        init(i);
    }
    Test()
    {
        init(0);
    }
    void print()
    {
        cout<<"mi="<<mi<<endl;
    }
};
int main()
{
    Test t;
    t.print();

    return 0;
}

運(yùn)行結(jié)果
C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題
可以看到,當(dāng)定義了一個(gè)init函數(shù)并調(diào)用之后,mi初始值為0
編譯器的行為--現(xiàn)代C++編譯器在不影響最終執(zhí)行結(jié)果的前提下,會(huì)盡力減少臨時(shí)對(duì)象的產(chǎn)生
代碼示例

#include <stdio.h>

class Test
{
    int mi;
public:
    Test(int i)
    {
        printf("Test(int i) : %d\n", i);
        mi = i;
    }
    Test(const Test& t)
    {
        printf("Test(const Test& t) : %d\n", t.mi);
        mi = t.mi;
    }
    Test()
    {
        printf("Test()\n");
        mi = 0;
    }
    int print()
    {
        printf("mi = %d\n", mi);
    }
    ~Test()
    {
        printf("~Test()\n");
    }
};

Test func()
{
    return Test(20);
}

int main()
{
    Test t = Test(10); // ==> Test t = 10;
    Test tt = func();  // ==> Test tt = Test(20); ==> Test tt = 20;

    t.print();
    tt.print();

    return 0;
}

猜想:生成臨時(shí)對(duì)象,用臨時(shí)對(duì)象初始化t,調(diào)用拷貝構(gòu)造函數(shù)
運(yùn)行結(jié)果
C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題
小結(jié)
1.直接調(diào)用構(gòu)造函數(shù)將產(chǎn)生一個(gè)臨時(shí)對(duì)象
2.臨時(shí)對(duì)象是性能的瓶頸,也是Bug的來(lái)源之一
3.實(shí)際工程開(kāi)發(fā)需要人為ide避開(kāi)臨時(shí)對(duì)象

二.經(jīng)典問(wèn)題

A.關(guān)于析構(gòu)的疑問(wèn)
a.單個(gè)對(duì)象創(chuàng)建時(shí)構(gòu)造函數(shù)的調(diào)用順序
1.調(diào)用父類(lèi)的構(gòu)造順序
2.調(diào)用成員變量的構(gòu)造函數(shù)--調(diào)用順序與聲明順序相同
3.調(diào)用類(lèi)自身的構(gòu)造函數(shù)--析構(gòu)函數(shù)與對(duì)應(yīng)構(gòu)造函數(shù)的調(diào)用順序相反

1.第一種情況--多個(gè)對(duì)象析構(gòu)時(shí)(析構(gòu)順序與構(gòu)造順序相反)
代碼示例

#include <iostream>
using namespace std;

class Member
{
    const char* ms;
public:
    Member(const char* s)
    {
        cout<<"Member(const char* s):"<< s<<endl;;

        ms = s;
    }
    ~Member()
    {
        cout<<"~Member():" <<ms<<endl;;
    }
};

class Test
{
    Member mA;
    Member mB;
public:
    Test() : mB("mB"), mA("mA")
    {
        cout<<"Test()"<<endl;
    }
    ~Test()
    {
        cout<<"~Test()"<<endl;
    }
};

Member gA("gA");

int main()
{
    Test t;  
    return 0;
}

代碼分析:先對(duì)定義的Member gA("gA")進(jìn)行構(gòu)造,再對(duì)Test類(lèi)中的成員變量的構(gòu)造函數(shù),最后對(duì)自身的構(gòu)造函數(shù)進(jìn)行調(diào)用,析構(gòu)順序與構(gòu)造順序相反
運(yùn)行結(jié)果
C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題
析構(gòu):對(duì)于棧對(duì)象和全局對(duì)象,類(lèi)似于入棧于出棧的順序,最后構(gòu)造的對(duì)象被最先析構(gòu),堆對(duì)象的析構(gòu)發(fā)生在使用delete的時(shí)候,于delete的使用順序相關(guān)
B.const關(guān)鍵字能否修飾類(lèi)的對(duì)象?如果可以,有什么特性?
1.const關(guān)鍵字能夠修飾對(duì)象
2.const修飾的對(duì)象為只讀對(duì)象
3.只讀對(duì)象的成員變量不允許被改變
4.只讀對(duì)象是編譯階段的概念,運(yùn)行時(shí)無(wú)效
C++中的const成員函數(shù)
1.const對(duì)象只能調(diào)用const的成員函數(shù)
2.const成員函數(shù)中只能調(diào)用const成員函數(shù)
3.const成員函數(shù)中不能直接改寫(xiě)成員變量的值
const成員函數(shù)的定義:Type ClassName::function(Type p)const--類(lèi)中的函數(shù)聲明與實(shí)際函數(shù)定義都必須帶const關(guān)鍵字
代碼示例

#include <iostream>
using namespace std;

class Test
{
    int mi;
public:
      int mj;
    Test(int i);
    Test(const Test& t);
    int getMi()const;
};

Test::Test(int i)
{
    mi = i;
}

Test::Test(const Test& t)
{

}

int Test::getMi()const
{
    return mi;
}

int main()
{
    const Test t(1);
    t.mj=1000;
    return 0;
}

由程序可得,const修飾了對(duì)象t,而下一步又對(duì)t.mj進(jìn)行賦值,這時(shí)程序會(huì)報(bào)錯(cuò),因?yàn)槭侵蛔x的
C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題
這時(shí)對(duì)程序進(jìn)行修改
C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題
程序運(yùn)行的結(jié)果如圖所示
C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題出現(xiàn)該問(wèn)題的原因是const成員函數(shù)中只能調(diào)用const成員函數(shù),需要在getMi加const來(lái)進(jìn)行修飾
進(jìn)行修改以及運(yùn)行結(jié)果圖
C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題
小結(jié)
1.對(duì)象的析構(gòu)順序與構(gòu)造順序相反
2.const關(guān)鍵字能夠修飾對(duì)象,得到只讀對(duì)象
3.只讀對(duì)象只能調(diào)用const成員函數(shù)

網(wǎng)站題目:C++--臨時(shí)對(duì)象與經(jīng)典問(wèn)題
標(biāo)題來(lái)源:http://muchs.cn/article40/jojoho.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)公司Google、品牌網(wǎng)站設(shè)計(jì)App設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)