類的動態記憶體分配

2021-06-21 16:19:03 字數 3306 閱讀 3287

1.靜態類成員:

private:

char * str;

int length;

static int objectnum; //靜態資料成員,為所有的物件所共享

上例中的objectnum就是靜態類成員,它是所有物件所共享的,如下圖:

在上例中,建立了三個物件,記憶體會給每個物件都分配資料單元用來儲存str和len,但是不會為每個物件都建立num_strings,在記憶體中只會建立乙個num_strings,供所有物件共享。靜態類資料成員的初始化不是在類的宣告檔案中進行的,而是在類的函式定義檔案中進行的。如在stringbad.cpp檔案中初始化,而不是在stringbad.h檔案中初始化。

2.特殊成員函式:

●預設建構函式:如果沒有定義建構函式,就會自動生成。

●預設析構函式:如果沒有定義析構函式,就會自動生成。

●複製建構函式:當用乙個物件初始化另外乙個物件時,如果我們沒有專門定義複製建構函式,則會自動生成複製建構函式,詳解見下面。

●賦值運算子:當用乙個物件初始化另外乙個物件時,如果我們沒有專門定義賦值運算子,則會自動生成賦值運算子,詳解見下面。

●位址運算子

3.複製建構函式:

class stringbad

;

int stringbad::objectnum = 0;    //靜態資料成員

stringbad::stringbad() //預設建構函式

stringbad::stringbad(const char * s) //建構函式

stringbad::~stringbad() //析構函式

ostream & operator<

int main()

在上例中,定義了乙個類stringbad,在類中定義了一些成員函式,然後使用sb2 = sb1,用sb1來初始化sb2,當用乙個物件初始化另外乙個物件時,就會呼叫複製建構函式,此時就呼叫了複製建構函式。

預設的複製建構函式逐個複製非靜態成員(成員複製也成為淺拷貝),複製的是成員的值。如在上例中,其實是將sb1.length賦給sb2.length,sb1.str賦給sb2.str,而物件的str成員儲存的是字串的位址,而不是字串本身,所以這種淺拷貝是將sb1.str和sb2.str指向同乙個地方,所以這種淺拷貝容易出問題,當將sb1.str指向的內容刪除時,其實也將sb2.str指向的內容也刪除了,再刪除sb2.str所指向的內容時就會出錯。

所以,此時我們就需要自己定義乙個複製建構函式來解決這種問題,將sb1.str和sb2.str指向不同的地方,但這兩個地方儲存的字串內容是一樣的(也就是深拷貝)。

淺拷貝和深拷貝的區別:淺拷貝是僅僅只拷貝字串的位址,使兩個指標指向同乙個地方。深拷貝是拷貝內容到另外乙個地方,使另乙個指標指向拷貝內容的地方,通過深拷貝兩個指標指向的位址就不同,但字串內容仍是相同的。

淺拷貝示意圖:

深拷貝示意圖:

stringbad::stringbad(const stringbad & st)   //複製建構函式,用於將乙個物件用於初始化另外乙個物件,如object1 = object2

警告:如果類中包含了使用new初始化的指標成員,則我們自己應定義乙個複製建構函式,以複製指向的資料,而不是複製指標,這被成為深拷貝。淺拷貝僅僅只是複製指標的值。

4.賦值運算子:

object2 = object1;
當我們使用以上語句用object1對object2進行初始化時,實際是分兩步來處理:先使用複製建構函式建立乙個臨時物件,然後通過複製運算子將臨時物件複製到新物件中。在第一步中,我們使用我們自己定義的複製建構函式來進行深拷貝;在第二步中,如果我們不自己定義賦值運算子時,我們進行的會是跟預設的複製建構函式一樣的淺拷貝,所以我們在這裡需要自己定義賦值運算子進行深拷貝。

這裡定義的賦值運算子如下:

stringbad & stringbad::operator=(const stringbad & sb)

5.整個專案例項**:

檔案結構:

int stringbad::objectnum = 0; //靜態資料成員

stringbad::stringbad() //預設建構函式

stringbad::stringbad(const stringbad & st) //複製建構函式,用於將乙個物件用於初始化另外乙個物件,如object1 = object2

stringbad::stringbad(const char * s) //建構函式

stringbad & stringbad::operator=(const stringbad & sb)

stringbad::~stringbad() //析構函式

ostream & operator<

main.cpp**:

#include #include "din.h"

using namespace std;

int main()

執行結果:

類和動態記憶體分配

part 1 靜態類成員特點 無論建立了多少物件,程式都只建立乙個靜態類變數副本。也就是說,類的所有物件共享乙個靜態成員。靜態資料成員在類宣告中宣告,在包含類方法的檔案中初始化。初始化時使用作用域運算子來指出靜態成員所屬的類。但如果靜態成員是const整數型別或列舉型,則可以在類宣告中初始化。par...

類和動態記憶體分配

整理自 c primer plus vector force1 50,60 vector force2 10,70 vector max max max force1,force2 version1 vector max const vector v1,const vector v2 version...

動態記憶體分配

在c 中建立乙個物件時,我們必須要為這個物件申請一塊記憶體,而且要用建構函式對這塊記憶體進行初始化。c 中的new和delete相對於c的庫函式malloc和free在這方面有很大的優勢,所以我們主要講的是運算子new和delete。當用new來建立乙個物件時,它會自動在堆裡為物件分配記憶體並且為這...