1. 程式人生 > >c/c++整理--c++面向物件(6)

c/c++整理--c++面向物件(6)

一、瞭解c++類各成員函式的關係

寫出下面程式碼的輸出結果

#include <iostream>

using namespace std;

class A
{
	int num;
public:
	A()
	{
		cout<<"Default constructor"<<endl;
	}
	~A()
	{
		cout<<"Desconstructor"<<endl;
		cout<<num<<endl;
	}
	A(const A& a)
	{
		cout<<"Copy constructor"<<endl;
	}
	void operator=(const A& a)
	{
		cout<<"Overload operator"<<endl;
	}
	void setnum(int n)
	{
		num = n;
	}
};

int main()
{
	A a1;
	A a2(a1);
	A a3=a1;
	A &a4=a1;
	a1.setnum(1);
	a2.setnum(2);
	a3.setnum(3);
	a4.setnum(4);

    return 0;
}
程式碼第34行,定義了一個物件a1,呼叫的是預設的建構函式。

程式碼第35行,用a1初始化一個物件a2,呼叫的是複製建構函式。

程式碼第36行,同上。注意,這裡不是呼叫賦值函式,這裡屬於物件a3的初始化,而不是賦值。若要呼叫賦值,必須為如下形式。

A a3;
a3 = a1;
程式碼第37行,定義a4為a1的一個引用,不呼叫建構函式或賦值函式。

程式碼第38~41行,呼叫各個物件的setnum()成員函式為私有成員num賦值。這裡注意,由於a4為a1的引用,因此a4.setnum實際上和a1.setnum一樣。

當main函式退出時,物件析構順序與呼叫建構函式順序相反,依次為a3,a2,a1.

輸出:

Default constructor
Copy constructor
Copy constructor
Desconstructor
3
Desconstructor
2
Desconstructor
4

二、c++類的臨時物件

已知class B以及Play()函式定義如下。

#include <iostream>

using namespace std;

class B
{
	int data;
public:
	B()
	{
		cout<<"default constructor"<<endl;
	}
	~B()
	{
		cout<<"destructed"<<endl;
	}
	B(int i) : data(i)
	{
		cout<<"constructor by parameter"<<data<<endl;
	}
};

B play(B b)
{
	return b;
}
分析下面兩個main()函式的輸出。

第一個main函式:

int main()
{
	B t1 = play(5);
	B t2 = play(t1);

    return 0;
}
第二個main函式:
int main()
{
	B t1 = play(5);
	B t2 = play(10);

    return 0;
}
解析:

  這裡呼叫play函式時,有兩種引數型別的傳遞方式。

  如果傳遞的引數是整型,那麼在其函式棧中首先會呼叫帶引數的建構函式,產生一個臨時物件,然後返回前(在return程式碼執行時)呼叫類的複製建構函式,生成臨時物件(這樣函式返回後主函式中的物件就被初始化了),最後這個臨時物件會在函式返回時(在return程式碼執行後)析構。

  如果傳遞的引數是B類的物件,那麼只有第一步與上面的不同,就是其函式棧中會首先呼叫複製建構函式產生一個臨時物件,其餘步驟完全相同。

  可以看出,兩種情況的區別是採用了不同的方法生成臨時物件(一個是呼叫帶引數的建構函式,另一個是呼叫複製建構函式)。

  在第一個main函式中,te使用了傳入整型數的方法呼叫play函式,而物件t2使用了傳入B的物件的方式呼叫play函式。在第二個main函式中,物件t1和t2都使用了傳入整型數的方式呼叫play函式。

第一個main函式執行結果:

constructor by parameter5         (呼叫帶引數的建構函式,在fun內生成臨時物件)
destructed                        (5傳入fun時生成的臨時物件析構)
destructed                        (t1傳入fun時產生的返回的臨時物件析構)
destructed                        (t2析構)
destructed                        (t1析構)
第二個main函式的執行結果:
constructor by parameter5         (呼叫帶引數的建構函式,在fun內生成臨時物件)
destructed                        (5傳入fun時生成的臨時物件析構)
constructor by parameter10        (呼叫帶引數的建構函式,在fun內生成臨時物件)
destructed                        (10傳入fun時生成的臨時物件析構)
destructed                        (t2析構)
destructed                        (t1析構)