前言
最近在學習C++的類如何構造,在W3Cschool上看到關于拷貝建構式的一個例子,記錄一下,
案例背景
這篇文章大致是構造了如下的一個Line類:
class Line{
public:
int getLength(void);
Line(int len); // 簡單建構式
Line(const Line &obj); // 拷貝建構式
~Line(); // 解構式
private:
int *ptr; //指向length
};
其中建構式和解構式的定義如下:
- 簡單建構式:
Line::Line(int len){
cout<< "Normal constructor allocating ptr." <<endl;
// 為指標分配記憶體
ptr = new int;
*ptr = len;
}
- 拷貝建構式:
Line::Line(const Line &obj){
cout<< "Copy constructor allocating ptr." <<endl;
ptr = new int;
// copy the value
//這里右式的運算順序是先獲取obj.ptr,再用'*'取值.
//因為是復制值,而不是復制地址,所以'='兩邊都要加上'*',
//否則,多個Line物件的長度都會被系結到一起,
*ptr = *obj.ptr;
}
- 解構式(在物件被銷毀時執行):
Line::~Line(void){
cout<< "Freeing memory!"<<endl;
delete ptr;
}
- 獲取
Line物件的長度,直接回傳指標指向的int型別資料
int Line::getLength(void){
return *ptr;
}
- 定義一個
display函式,用于輸出Line物件的長度:
void display(Line obj){
cout<< "Length of line : "<<obj.getLength() <<endl;
}
正文
對于以下main函式的內容:
int main(){
Line line1(10);
Line line2(line1); //這里呼叫了拷貝建構式
display(line1);
display(line2);
return 0;
}
預期的輸出是:
Normal constructor allocating ptr.
Copy constructor allocating ptr.
Length of line : 10
Length of line : 10
Freeing memory!
Freeing memory!
但實際輸出是:
拷貝建構式和解構式被呼叫了好幾次
Normal constructor allocating ptr.
Copy constructor allocating ptr.
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
Freeing memory!
Freeing memory!
分析
在設定斷點和除錯代碼之后,發現原因:
- display函式的函式引數是值傳遞,也就是說在呼叫時會創建函式引數(Line物件)的副本,并且display函式執行完之后,副本會被洗掉,
- 也就是說,每執行一次display函式,都會觸發對拷貝建構式和解構式的呼叫,就會輸出如下的文本:
Copy constructor allocating ptr.
Length of line : 10
Freeing memory!
- 而輸出結尾的兩個
Freeing memory!是由于C/C++的區域變數是存盤在堆疊區stack的,堆疊區由編譯器自動分配和釋放記憶體, - 當程式執行到
return 0;的時候,區域變數line1和line2被銷毀,故解構式被呼叫, - 并且需要注意的是,這兩個輸出的順序是:
Freeing memory! --> 對應line2的銷毀
Freeing memory! --> 對應line1的銷毀
- 這是因為變數是存盤在堆疊區中的,遵循FILO(First In, Last Out)的順序,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/501065.html
標籤:其他
上一篇:JPA作持久層操作
