由一道面試題想到的——c++ constructor destructor的調用

來源:互聯網
上載者:User

昨天看到一個moto公司的面試題,題目如下:

#include <iostream>

Using namespace std ;

class human

{

public:

human()

{

 human_num++;

}

static int human_num;

 

 

 

 

~human()

{

human_num--;

print();

}

void print()

{

cout<<"human nun is: "<<human_num<<endl;

}

protected:

private:

};

int human::human_num = 0;

human f1(human x)

{

x.print();

return x;

}

int main(int argc, char* argv[])

{

human h1;

h1.print();

human h2  = f1(h1);

h2.print();

return 0;

}

寫出程式的輸出結果。。。。。只 知道輸出5行,但是不知道每行 human_num的值是多少??

我們先不看這個題目,我們先來瞭解一下建構函式在按值傳向函數,以及按值從函數返回的時候會發生什麼:

1、將對象按值傳給函數的時候,首先會建立該對象的一個副本,將這個副本傳給函數,但是在建立這個副本的時候,不會調用建構函式,而在這個函數返回的時候會調用解構函式。

2、函數按值返回對象的時候,也會建立返回對象的一個副本,同樣的也不會調用建構函式,在返回後調用解構函式銷毀該對象。

我們先來看下面的一個程式:

/*
 Constructor and destructor
*/
#include <iostream>
#include <string>
using namespace std ;

class test
{
 public:
  //Constructor
  test( string s ):str(s)
  {
   cout << "Constructing " << endl ;
  }
  
  //Destructor
  ~test()
  {
   cout << "Destructing " << endl ;
  }
  
  string getValue()
  {
   return str ;
  }

 private:
  string str ;
} ;

void display( test t )
{
 cout << t.getValue() << endl ;
}

test getTest()
{
 return test("Jun") ;
}

void main()
{
 //這裡很顯然調用了一次建構函式,程式會輸出:constructing
 test te = test("Guo") ; 

//在向函數按值傳對象的時候,會建立傳遞的對象的副本
//但是此時不會調用建構函式。不會有constructing輸出
 display(te) ;
 //在函數返回的時候,會調用其destructor銷毀剛才的副本 
 //程式輸出:Destructing

 getTest() ; 

 //在getTest裡面我們建立了一個對象,因此會有一次constructor的調用
 //程式輸出:constructing ,我們知道在程式返回的時候,會產生一個副本返回
 //因此實際上在函數裡面會有destructor的調用,然後再返回到main函數裡面
 //的對象也會被destructed,因此會再次輸出destructing,最後銷毀最初的

//對象。

}

//最終程式的結果:
//constructing
//Destructing
//Guo
//destructing
//constructing
//destructing
//destructing
//destructing

回過頭來我們看看上面的例子:

#include <iostream>

Using namespace std ;

class human

{

public:

human()

{

 human_num++;

}

static int human_num;

~human()

{

human_num--;

print();

}

void print()

{

cout<<"human nun is: "<<human_num<<endl;

}

protected:

private:

};

int human::human_num = 0;

human f1(human x)

{

x.print();

return x;

}

int main(int argc, char* argv[])

{

human h1;

//h1被構造,human_num = 1

h1.print();

//h1作一個拷貝,然後將拷貝傳入函數,沒有建構函式被調用,因此會輸出1

//返回的是一個對象,因此還是會做一個拷貝,然後返回,此時調用一次溪溝函數,臨時拷貝被析構,human_num=0 ,於是h2.print(),同樣輸出0,再h1,h2被析構,分別輸出-1,-2

human h2  = f1(h1);

h2.print();

return 0;

}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.