首先解釋一下文章標題,聽起來有點拗口,意思是:具有返回值的函數,在調用時以及返回時都做了哪些事情(這些事情往往從代碼表面是看不到的)。
一、原理
關於函數的返回值,先說下 return 語句,return 語句結束當前正在執行的函數,並將控制權返回給調用此函數的函數。有兩種形式:
1.return; //不帶返回值的函數中(void)
不帶返回值的 return 語句只能用於返回類型為 void 的函數。但是注意:在返回類型為void的函數中,return 語句也不是必須的,隱式的 return 發生在函數的最後一個語句完成時。
一般情況下,返回類型為 void 的函數使用 return 語句是為了引起函數的強制結束(類似於循環結構中的break語句)。
2.return expression: //帶返回值的函數中(非void)
此情況下,返回值的類型必須和函數的返回類型相同,或者能隱式轉化為函數的返回類型。
函數的返回值:用於初始化在調用函數出創建的臨時對象(temporary object)。
對於具有返回值的函數,在函數調用時(如求解表達式),需要一個地方存儲器運算結果,此時編譯器會創建一個沒有命名的對象-----臨時對象。
如:
[cpp]
...
int add(int a, int b)
{
return a + b ;
}
....
int a = 1;
int b = 2;
int c = add(a, b); //create temporary, delete it after executing this statement
...
...
int add(int a, int b)
{
return a + b ;
}
....
int a = 1;
int b = 2;
int c = add(a, b); //create temporary, delete it after executing this statement
...
上面的代碼中,在 int c = add (a, b);時,發生了如下事情:
首先:創建了一個臨時對象,如temp。
然後:將函數的返回值 a+ b 的副本 復制給 temp;
最後:將temp 的副本復制給 變量 c,並刪除臨時變量 temp
注:在英語中,C++ 程序員通常用temporary 這個術語來代替 temporary object。
二、例子
為了更清晰地看到具有具有返回值函數之作為,下面以一個類的運行情況說明:
[cpp]
#include <iostream>
using namespace std;
class A
{
private:
int m_x;
public:
A(int x=0):m_x(x){cout<<"constructor, value: "<<m_x<<endl;}
A(const A& a)
{
m_x = a.m_x;
cout<<"copy constructor, value: "<<m_x<<endl;
}
A& operator=(const A& a)
{
m_x = a.m_x;
cout<<"assignment operator, value: "<<m_x<<endl;
return *this;
}
~A(){cout<<"destructor, value: "<<m_x<<endl;}
A getOneObject(int x)
{
cout<<"in fun call"<<endl;
A a(0);
a.m_x =x;
return a;
}
};
int main()
{
A a1(1);
A a2(2);
cout<<"before fun call"<<endl;
a2= a1.getOneObject(3);
cout<<"after fun call"<<endl;
cout<<"before quit"<<endl;
return 0;
}
#include <iostream>
using namespace std;
class A
{
private:
int m_x;
public:
A(int x=0):m_x(x){cout<<"constructor, value: "<<m_x<<endl;}
A(const A& a)
{
m_x = a.m_x;
cout<<"copy constructor, value: "<<m_x<<endl;
}
A& operator=(const A& a)
{
m_x = a.m_x;
cout<<"assignment operator, value: "<<m_x<<endl;
return *this;
}
~A(){cout<<"destructor, value: "<<m_x<<endl;}
A getOneObject(int x)
{
cout<<"in fun call"<<endl;
A a(0);
a.m_x =x;
return a;
}
};
int main()
{
A a1(1);
A a2(2);
cout<<"before fun call"<<endl;
a2= a1.getOneObject(3);
cout<<"after fun call"<<endl;
cout<<"before quit"<<endl;
return 0;
}
輸出結果: