欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++ 臨時(shí)對(duì)象的來(lái)源

 更新時(shí)間:2013年01月02日 17:56:54   作者:  
大家可能對(duì)這個(gè)臨時(shí)對(duì)象這個(gè)概念還不是很清楚,那么首先我們花一些時(shí)間來(lái)理解臨時(shí)對(duì)象

首先看下面一端代碼:

復(fù)制代碼 代碼如下:

 #include <iostream>
 void swap( int &a,int &b)
 {
     int temp;
     temp=a;
     a=b;
     b=temp;
 }

 int main(int argc,char** argv)
 {
     int a=1,b=2;
     swap(a,b);
     std::cout<<a<<"-----"<<b<<std::endl;
     return 0;
 }

 結(jié)果為
 2-----1  
 可能大多數(shù)園友,認(rèn)為"int temp"是"臨時(shí)對(duì)象",但是其實(shí)不然,"int temp"僅僅是swap函數(shù)的局部變量。

臨時(shí)對(duì)象是代碼中看不到的,但是實(shí)際程序中確實(shí)存在的對(duì)象。臨時(shí)對(duì)象是可以被編譯器感知的。


為什么研究臨時(shí)對(duì)象?
主要是為了提高程序的性能以及效率,因?yàn)榕R時(shí)對(duì)象的構(gòu)造與析構(gòu)對(duì)系統(tǒng)開(kāi)銷(xiāo)也是不小的,所以我們應(yīng)該去了解它們,知道它們?nèi)绾卧斐?,從而盡可能去避免它們。

臨時(shí)對(duì)象建立一個(gè)沒(méi)有命名的非堆對(duì)象會(huì)產(chǎn)生臨時(shí)對(duì)象。(不了解什么是堆對(duì)象和非堆對(duì)象,可以參考C++你最好不要做的這一博文,這里面有介紹。)這種未命名的對(duì)象通常在三種條件下產(chǎn)生:為了使函數(shù)成功調(diào)用而進(jìn)行隱式類(lèi)型轉(zhuǎn)換時(shí)候、傳遞函數(shù)參數(shù)和函數(shù)返回對(duì)象時(shí)候。

那么首先看看為了使函數(shù)成功調(diào)用而進(jìn)行隱式類(lèi)型轉(zhuǎn)換。

復(fù)制代碼 代碼如下:

 #include <iostream>
  int countChar(const std::string & s,const char c)
  {
      int count=0;
      for(int i=0;i<s.length( );i++)
      {
          if(*(s.c_str( )+i) == c)
          {
              count++;
         }
    }
     return count;
 }

 int main(int argc,char** argv)
 {
     char buffer[200];
     char c;
     std::cout<<"please input the string:";
     std::cin>>buffer;
     std::cout<<"please input the char which you want to chount:";
     std::cin>>c;
     int count=countChar(buffer,c);
     std::count<<"the count is:"<<count<<std::endl;
     return 0;
 }

結(jié)果為:



這里調(diào)用函數(shù)countChar(const std::string& s,const char& c),那么我們看看這個(gè)函數(shù)的形參是const std::string &s,形參類(lèi)型為const std::string,但是實(shí)際上傳遞的是char buffer[200]這個(gè)數(shù)組。其實(shí)這里編譯器為了使函數(shù)調(diào)用成功做了類(lèi)型轉(zhuǎn)換,char *類(lèi)型轉(zhuǎn)換為了std::string類(lèi)型,這個(gè)轉(zhuǎn)換是通過(guò)一個(gè)賦值構(gòu)造函數(shù)進(jìn)行的,以buffer做為參數(shù)構(gòu)建一個(gè)std::string類(lèi)型的臨時(shí)對(duì)象。當(dāng)constChar返回時(shí),即函數(shù)撤銷(xiāo),那么這個(gè)std::string臨時(shí)對(duì)象也就釋放了。但是其實(shí)從整個(gè)程序上來(lái)說(shuō)臨時(shí)對(duì)象的構(gòu)造與釋放是不必要的開(kāi)銷(xiāo),我們可以提高代碼的效率修改一下代碼避免無(wú)所謂的轉(zhuǎn)換。所以知道臨時(shí)對(duì)象的來(lái)源,可以對(duì)程序性能上有一個(gè)小小提升。

   注意僅當(dāng)通過(guò)傳值方式傳遞對(duì)象或者傳遞常量引用參數(shù),才會(huì)發(fā)生這類(lèi)型的轉(zhuǎn)換,當(dāng)傳遞非常量引用的參數(shù)對(duì)象就不會(huì)發(fā)生。因?yàn)閭鬟f非常量的引用參數(shù)的意圖就是想通過(guò)函數(shù)來(lái)改變其傳遞參數(shù)的值,但是函數(shù)其實(shí)是改變的類(lèi)型轉(zhuǎn)換建立的臨時(shí)對(duì)象,所以意圖無(wú)法實(shí)現(xiàn),編譯器干脆就直接拒絕。

第二種情況是大家熟悉的函數(shù)傳遞參數(shù)的時(shí)候,會(huì)構(gòu)造對(duì)應(yīng)的臨時(shí)對(duì)象??聪旅嬉欢未a運(yùn)行的結(jié)果想必就一清二楚了。

復(fù)制代碼 代碼如下:

 #include<iostream>
 class People
 {
     public:
         People(std::string n,int a)
         :name(n),age(a)
         {
             std::count<<"h2"<<std::endl;
         }
        People( )
        {
            std::count<<"h1"<<std::endl;
        }
        People(const People& P)
        {
            name=p.name;
            age=p.age;
            std::cout<<"h3"<<std::endl;
        }
        std::string name;
        int age;
};

void swap(People p1,People p2)
{
    People temp;
    temp.age=p1.age;
    temp.name=p1.name;
    p1.age=p2.age;
    p1.name=p2.name;
    p2.age=temp.age;
    p2.name=temp.name;
}

int main(int argc, char ** argv)
{
    People p1("tom",18),p2("sam",19);
    swap(p1,p2);
    return 0;
}


結(jié)果為:



這里分析下前面兩個(gè)"h2"是通過(guò)調(diào)用構(gòu)造函數(shù)People(std::string n,int a)打印出來(lái)的,而"h3"就是通過(guò)調(diào)用復(fù)制構(gòu)造函數(shù)People(const People&)而建立臨時(shí)對(duì)象打印出來(lái)的,h1是調(diào)用默認(rèn)構(gòu)造函數(shù)People( )打印出來(lái)的。那么怎么避免臨時(shí)對(duì)象的建立呢?很簡(jiǎn)單,我們通過(guò)引用實(shí)參而達(dá)到目的

void swap(People &p1,People &p2)
第三種情景就是函數(shù)返回對(duì)象時(shí)候。這里要注意臨時(shí)對(duì)象的創(chuàng)建是通過(guò)復(fù)制構(gòu)造函數(shù)構(gòu)造出來(lái)的。

例如   const Rationanl operator+(Rationanl a,Rationanl b)該函數(shù)的返回值的臨時(shí)的,因?yàn)樗鼪](méi)有被命名,它只是函數(shù)的返回值。每回必須為調(diào)用add構(gòu)造和釋放這個(gè)對(duì)象而付出代價(jià)。

復(fù)制代碼 代碼如下:

 #include <iostream>
 class Rationanl
 {
     public:
         Rationanl(int e,int d)
         :_elemem(e),_denom(d)
         {
             std::cout<<"h2"<<std::endl;
         }
         void show( ) const;
         int elemem() const {return _elemem;}
         int denom() const {return _denom;}
         void  setElemon(int e){_elemon=e;}
         void  setDenom(int d) {_denom=d;}
         Rationanl(const Rationanl &r);
         Rationanl & operator=(const Rationanl &r);
     private:
         int _elemem;
         int _denom;
 };
 Rationanl::Rationanl(const Rationanl &r)
 {
     setElemon(r.elemon( ));
     setDenom(r.denom( ) );
     std::cout<<"h3"<<std::endl;
 }
 Rationanl & Rationanl::operator=(const Rationanl &r)
 {
     setElemon(r.elemon( ));
     setDenom(r.denom( ) );
     std::cout<<"h4"<<std::endl;
     return *this;
 }

 void Rationanl::show( )
 {
         std::cout<<_elemen<<"/"<<_denom<<std::endl;
 }
 const Rationanl operator*(const Rationanl lhs,const Rationanl rhs)
 {
     return Rational result(lhs.elemen*rhs.elemen,rhs.denom*rhs.denom);
 }

 int main(int argc,char **argv)
 {
     Rationanl r1(1,2),r2(1,3)
     Rationanl r3=r1*r2;    //GCC做了優(yōu)化,沒(méi)有看到臨時(shí)變量。編譯器直接跳過(guò)建立r3,使用賦值符號(hào)
     r3.show( );
     //相當(dāng)于  (r1*r2).show( );
     return 0;
 }

結(jié)果為:



這里很可惜沒(méi)有看到我們想到看到的結(jié)果,結(jié)果應(yīng)該為h2,h2,h2,h3,h4,應(yīng)該是在返回值的時(shí)候有一個(gè)賦值構(gòu)造函數(shù),建立臨時(shí)變量的,后來(lái)經(jīng)筆者網(wǎng)上查找資料證實(shí)GCC做了優(yōu)化。

相關(guān)文章

  • 用C++的odeint庫(kù)求解微分方程

    用C++的odeint庫(kù)求解微分方程

    求解微分方程的數(shù)值解一般使用MATLAB等數(shù)值計(jì)算軟件,其實(shí)C++也可以求解微分方程,需要用到odeint庫(kù),它是boost庫(kù)的一部分。官方教程和示例比較晦澀,本文力求用較短的篇幅介紹它的基本用法,需要的朋友可以參考下面文章的具體內(nèi)容
    2021-09-09
  • 關(guān)于c語(yǔ)言的一個(gè)小bug詳解

    關(guān)于c語(yǔ)言的一個(gè)小bug詳解

    以下是對(duì)c語(yǔ)言中的一個(gè)小bug進(jìn)行了詳細(xì)的分析介紹。需要的朋友可以過(guò)來(lái)參考下
    2013-08-08
  • 2~62位任意進(jìn)制轉(zhuǎn)換方法(c++)

    2~62位任意進(jìn)制轉(zhuǎn)換方法(c++)

    下面小編就為大家?guī)?lái)一篇2~62位任意進(jìn)制轉(zhuǎn)換方法(c++)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-06-06
  • QT Creator+OpenCV實(shí)現(xiàn)圖像灰度化的示例代碼

    QT Creator+OpenCV實(shí)現(xiàn)圖像灰度化的示例代碼

    這篇文章主要為大家詳細(xì)介紹了QT如何利用Creator和OpenCV實(shí)現(xiàn)圖像灰度化效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下
    2022-12-12
  • 通過(guò)GDB學(xué)習(xí)C語(yǔ)言的講解

    通過(guò)GDB學(xué)習(xí)C語(yǔ)言的講解

    今天小編就為大家分享一篇關(guān)于通過(guò)GDB學(xué)習(xí)C語(yǔ)言的講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • C語(yǔ)言實(shí)現(xiàn)猜數(shù)游戲

    C語(yǔ)言實(shí)現(xiàn)猜數(shù)游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)猜數(shù)游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-12-12
  • Qt實(shí)現(xiàn)數(shù)據(jù)進(jìn)行加密、解密的步驟

    Qt實(shí)現(xiàn)數(shù)據(jù)進(jìn)行加密、解密的步驟

    本文主要介紹了Qt實(shí)現(xiàn)數(shù)據(jù)進(jìn)行加密、解密的步驟,包含QCryptographicHash和Qt-AES兩種庫(kù)的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • C語(yǔ)言利用EasyX繪制小企鵝表情包

    C語(yǔ)言利用EasyX繪制小企鵝表情包

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言如何利用EasyX繪圖庫(kù)實(shí)現(xiàn)繪制可愛(ài)的小企鵝表情包,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-12-12
  • C語(yǔ)言中的5種簡(jiǎn)單排序算法(適合小白)

    C語(yǔ)言中的5種簡(jiǎn)單排序算法(適合小白)

    在編程練習(xí)時(shí)我們經(jīng)常會(huì)遇到一些將一串亂序的數(shù)字排列成有序的數(shù)列(遞增,遞減)的問(wèn)題,以此起到解決問(wèn)題的效果,下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中的5種簡(jiǎn)單排序算法的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • C語(yǔ)言實(shí)現(xiàn)班級(jí)檔案管理系統(tǒng)課程設(shè)計(jì)

    C語(yǔ)言實(shí)現(xiàn)班級(jí)檔案管理系統(tǒng)課程設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)班級(jí)檔案管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12

最新評(píng)論