C++:01.從C到C++:淺拷貝,優化規則,內存分配

new int[20]和new int[20]()
有()初始化爲該類型的默認值       沒有(爲隨機值)     開闢單個元素可以在()內隨意初始化,但開闢數組是()內不能寫入數字


類的成員方法在類體內定義和在類外定義:
1.類外定義的成員方法,在方法名字前面加類類型的作用域

2.類外定義的在調用時,有函數的正常開銷(函數運行需要再棧上開闢內存);在類體內定義的函數,都被自動處理成inline內聯函數(沒有調用開銷)


內存擴容(淺拷貝和深拷貝):

對於內置類型(指的就是int等),擴容時,可以直接使用memcpy&realloc等內存操作函數;

但是如果是對象類型,擴容時,一定不能夠使用memcpy&realloc!!!

理由:這種操作是淺拷貝【如果對象的屬性裏有指針,則指針指向的是同一空間(訪問的是同一內存),這種方法不可取,但如果沒有指針,則無所謂】

在代碼上如何解決淺拷貝問題?
                  1.提供自定義的拷貝構造函數和賦值重載函數operator=
                  2.拷貝構造函數和賦值重載函數聲明成private的

一般來說最好自己寫深拷貝,重新定義一個堆空間,將之前的內容複製到該空間。

CQueue(const CQueue &src)//隊列
{
_pQue = new int[src._size];
memcpy(_pQue, src._pQue, sizeof(int)*src._size);
如果隊列裏放的是內置類型,可以用memcpy,如果是對象或帶指針的,就只能用循環,一個一個賦值。
_front = src._front;
_rear = src._rear;
_size = src._size;
}

 優化規則:

用臨時對象初始化同類型新對象的時候,臨時對象就不產生了。所以用構造臨時對象的方式,直接構造新對象就行了
           Test t3 = Test(10, 10);

在優化中注意的地方:

1:函數調用傳參要傳對象的引用!                                 eg:Test GetTestObject(Test &t)

2:函數返回值當中不要返回一個已經存在的對象,返回臨時對象!!!  eg:return Test(value);

3:用初始化的方式接收一個返回值爲對象的函數           eg: Test t2 = GetTestObject(t1);

補充解釋:

函數返回值:小於4字節用eax寄存器。小於8字節,用eax,edx兩個寄存器。當返回值大於8字節時,會產生臨時量,當返回的是對象不管多大都會產生臨時量,因爲對象的構造一定會分配內存。

在調用函數之前會查看函數返回值如果返回值不爲空,這個時候就已經在main函數棧幀上開闢了臨時量的空間,就算函數沒有參數,不需要參數傳遞,但其實還是傳遞了該臨時量空間的地址。函數返回局部變量的時候就拷貝到這個臨時量上了。

在瞭解了上述的基礎上,我來詳細解釋下優化規則:

1、函數調用傳參要傳對象的引用! 如果不傳引用,而是用值傳遞的方法,就會多實現一步對參數t的拷貝構造,並且出函數也會調用析構函數。

2、函數返回值中返回臨時對象!  如果返回的是已存在的對象,這個對象肯定是函數裏的局部變量,首先建立它的時候就會調用構造函數,出函數的時候先拷貝構造main函數棧幀上的臨時對象,再對其本身進行析構。

1、用初始化的方式接收一個返回值爲對象的函數!   如果不以初始化的方式接收,也就是說用的是已經存在的對象接收,當然會使用臨時量調用賦值函數的重載。並且這個臨時量也會析構。


內存分配:

我一直認爲了解內存分配,可以更全面的理解代碼。但之前一直是零零散散使用,並沒有全面的認識,今天我打算對其進行簡單整理:

 大體上是這樣分配的,如果瀏覽該博文的哪位大佬發現有什麼需要修改或補充的地方,還請及時告知我,不勝感激。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章