淺談C++的淺拷貝呈現的錯誤。本站提示廣大學習愛好者:(淺談C++的淺拷貝呈現的錯誤)文章只能為提供參考,不一定能成為您想要的結果。以下是淺談C++的淺拷貝呈現的錯誤正文
之前看一些材料提到淺拷貝的問題,即在復制對象時,只是對對象中的數據成員停止復雜的賦值,默許拷貝結構函數執行的也是淺拷貝。假如對象中存在靜態成員,如指針,那麼僅僅做淺拷貝是不夠的,並且容易引發錯誤,最經典的例子:
#include <iostream> #include <stdio.h> using namespace std; class A{ public: A(){m_p = new int(10);}; ~A(){cout << "destruction function" << endl;delete m_p;}; int* m_p; }; void copyTest(A atmp){ ; } int main(){ A a; copyTest(a); }
執行這段代碼會呈現解體,由於析構函數裡的delete m_p執行了兩次,而m_p指向的是同一塊內存。由於在調用copyTest時傳入了對象a,atmp應用a作為參數執行了默許拷貝結構函數,但是只是復雜地把對象a的m_p的內存地址拷貝給atmp的m_p,因而這個時分atmp.m_p只是指向了和a.m_p相反的內存塊。
當copyTest執行終了後,暫時變量atmp會被銷毀,這個時分析構函數被調用,delete了m_p指向的內存。而當main函數執行終了後,a對象也需求被銷毀,這個時分析構函數再次被執行,而這個時分m_p曾經不知道指向什麼中央了,delete操作引發順序解體。
處理這個問題的辦法有很多:一種辦法是完成智能指針,對m_p停止援用計數,當援用值為0時才執行delete;也可以每次把m_p的初始值設為NULL,每次執行delete操作前先反省m_p能否為NULL,delete後再讓m_p指向NULL,這個辦法其實道理和智能指針差不多,只是智能指針更合理無效天時用類停止管理;還有一種做法是重寫拷貝結構函數,確保在對象復制時停止深拷貝,即重新分配內存空間,並且把a中m_p指向內存的內容拷貝到分配的空間。
以上這種狀況只要在應用“值傳遞”復制對象時才發作,假如我們傳遞的是指針,就不會有這種狀況了:
#include <iostream> #include <stdio.h> using namespace std; class A{ public: A(){m_p = new int(10);}; ~A(){cout << "destruction function" << endl;delete m_p;}; int* m_p; }; void copyTest(A* atmp){ ; } int main(){ A* a; copyTest(a); }
由於傳遞到copyTest的參數只是一個地址,指向的還是對象a,並沒有發作對象的復制,當然就不存在下面的深淺拷貝問題了。
以上就是為大家帶來的淺談C++的淺拷貝呈現的錯誤全部內容了,希望大家多多支持~