如何定義乙個只能在堆上(棧上)生成物件的類?(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 這兩種方式是有區別的。靜態建立乙個類物件,是由編譯器為物件在棧空間中分配記憶體,是通過直接移動棧頂指標,挪出適當的空間,然後在這片記憶體空間上呼叫建構函式形成乙個棧物件。使用這種方法,直接呼叫類的建...