C 定義乙個只能在堆上(棧上)生成物件的類

2021-08-04 09:39:58 字數 1616 閱讀 3460

如何定義乙個只能在堆上(棧上)生成物件的類?

(1)靜態建立

class a;

a a;

靜態建立乙個類的物件,編譯器為該物件在棧中分配記憶體,通過直接移動棧頂指標,挪出適當空間;然後呼叫類的建構函式形成乙個棧上的物件。

注意:直接呼叫類的建構函式。當銷毀物件時,呼叫類的析構函式。

(2)動態建立

動態建立類物件,使用new運算子將物件簡歷在堆空間中。

class a;

a *ptr = new a();

a *ptr = new a;

首先執行operator new()函式,在堆中找到合適空間分配;然後呼叫建構函式初始化。

注意:間接呼叫類的建構函式。

要求類物件只能建在堆上,就是說使用者不能呼叫類的建構函式。將建構函式設為私有?

class b 

public:

~b() {}

};//error!b::b()不可訪問

b * p2 = new b;

new無法建立物件。

繼續分析:將物件建立在棧上時,編譯器管理該物件的整個生命週期。編譯器為類物件分配空間時,會先檢查類的析構函式的訪問性。如果編譯器無法呼叫析構函式則不會再棧上分配空間。

class c 

private:

~c() {}

};// on heap ok

c * p3 = new c;

// on stack error!

c c;

既然建構函式不能設為私有,將析構函式設為私有,然後用new呼叫建構函式在堆上分配,就可以達到禁止使用者在棧上建立物件的目的。

既然是在堆上,程式設計師控制物件的生命週期。顯示呼叫new,顯示呼叫delete。

class c 

void destory()

private:

~c() {}

};

還是有不滿意的地方。比如繼承。a若作為基類,析構函式通常宣告為虛函式,子類重寫,實現多型。因此析構函式可以設定為protected,使用者無法訪問,子類可以訪問。

比較考慮周全的如下示:

class a 

~a()

public:

static a * create()

void destory()

};a * p1 = a::create();

cout

<< &(*p1) << endl;

p1->destory();

只有使用new運算子,物件才會建在堆上。因此使用者禁用new就可以實現。將operator new()過載設為私有即可。如下:

class d 

void

operator delete(void * ptr) {}

public:

d() {}

~d() {}

};// error:函式不可訪問

d * p4 = new d;

如何定義乙個只能在堆上(棧上)生成物件的類

1 只能在堆上生成物件 將析構函式設定為私有。原因 c 是靜態繫結語言,編譯器管理棧上物件的生命週期,編譯器在為類物件分配棧空間時,會先檢查類的析構函式的訪問性。若析構函式不可訪問,則不能在棧上建立物件。2 只能在棧上生成物件 將new 和 delete 過載為私有。將new操作設定為私有,那麼第一...

如何定義乙個只能在堆上(棧上)生成物件的類

在c 中,類的物件建立分為兩種 靜態建立乙個類物件,是由編譯器為物件在棧空間分配記憶體,通過直接移動棧頂指標,挪出適當的空間,然後在這片記憶體空間上呼叫建構函式形成乙個棧物件。使用這種方法,直接呼叫類的建構函式。動態建立類物件,是使用new 運算子將物件建立在堆空間中。這個過程分為兩步 如何限制類物...

如何定義乙個只能在堆上(棧上)生成物件的類

在c 中,類的物件建立分為兩種,一種是靜態建立,如a a 另一種是動態建立,如a ptr new a 這兩種方式是有區別的。靜態建立乙個類物件,是由編譯器為物件在棧空間中分配記憶體,是通過直接移動棧頂指標,挪出適當的空間,然後在這片記憶體空間上呼叫建構函式形成乙個棧物件。使用這種方法,直接呼叫類的建...