C 如何實現類物件只能動態分配或只能靜態分配

2021-08-20 23:57:46 字數 1798 閱讀 6350

c++中建立類的物件有兩種方式:

(1)靜態建立,例如 a a;

靜態建立乙個類物件,就是由編譯器為物件在棧空間中分配記憶體。使用這種方法,是直接呼叫類的建構函式。

(2)動態建立,例如 a* p = new a();

動態建立乙個類物件,就是使用new運算子為物件在堆空間中分配記憶體。這個過程分為兩步:第一步執行operator new( )函式,在堆空間中搜尋一塊記憶體並進行分配;第二步呼叫類的建構函式構造物件。這種方法是間接呼叫類的建構函式。

如何實現只能動態分配或者只能靜態分配呢?

類物件只能通過new運算子建立在堆空間中,不能靜態分配,即不能直接呼叫類的建構函式。

怎樣才能實現類的建構函式不能被直接呼叫呢?首先想到的就是將類的建構函式設為private,這樣就無法在類外部呼叫建構函式來構造物件了,只能使用new運算子。但是,這種做法行不通。為什麼???因為前邊已經說過,new運算子過程分為兩步,c++提供new運算子的過載,其實只允許過載operator new( )函式,而operator()函式用於記憶體分配,無法提供建構函式功能。因此,將建構函式設為private不可行。

從另外乙個角度分析,物件靜態分配時,是由編譯器負責分配記憶體空間的,呼叫建構函式在棧空間中構造物件。當物件使用完畢,編譯器又會呼叫析構函式來釋放棧空間中的類物件。如果編譯器無法呼叫類的析構函式,會怎樣呢?其實,編譯器在為類物件分配棧空間時,會先檢查類的析構函式的訪問性(其實不光是析構函式,只要是非靜態的函式,編譯器都會進行檢查)。如果類的析構函式在類外部無法訪問,則編譯器拒絕在棧空間上為類物件分配記憶體。

因此,可以將析構函式設為private,這樣就無法在棧上建立類物件了。實現如下:

class a  

void

destory()

private

: ~a

(){}

};

這樣在使用a a; 來建立物件時會編譯錯誤,提示析構函式無法訪問。這樣就只能用new運算子來建立物件了,並且建構函式可以呼叫,因為是public。但是必須提供乙個destory函式來實現記憶體空間的釋放。

上面的方法雖然能實現只能動態建立物件,但是有乙個缺點:無法實現繼承。因為如果a作為基類的話,則析構函式通常要設為virtual,然後在子類中被重寫,以實現多型。因此析構函式不能設為private。為了解決這個問題該怎麼辦呢?別忘了,c++還提供了第三種訪問控制,就是protected。將析構函式設為protected,類外無法訪問protected成員,但是子類可以訪問。完美解決問題。實現如下:

class a  

~a(){}

public

: static

a* create

()

void

destory()

};

增加create函式是為了讓**看起來更統一,呼叫create函式在堆上建立類a物件,呼叫destory函式來釋放記憶體。

只有使用new運算子,物件才會被建立在堆上。因此只要限制new運算子就可以實現類物件只能建立在棧上。可以將new運算子設為私有,實現如下:

class a  

//注意函式的第乙個引數和返回值都是固定的

void

operator

delete(void

* ptr){} //過載了new就需要過載delete

public

: a

(){}

~a(){}

};

類如何實現只能靜態分配和只能動態分配

首先,在c 中,類物件的建立方式有兩種 靜態建立類物件,如a a 這是由編譯器為物件在棧空間中分配記憶體。動態建立類物件,如a p new a 使用new運算子為物件在棧空間分配記憶體。兩種方式區別 靜態建立類物件 是指全域性物件,靜態物件,以及分配在棧區域內的物件,編譯器對它們的記憶體分配是在編譯...

只能動態 靜態分配類物件

只能動態分配類物件.cpp 定義控制台應用程式的入口點。include stdafx.h include using namespace std 只在堆上建立 把析構函式設定為私有即可,但是這樣的話以它為基類的派生類就不能訪問析構函式來釋放資源了 因此設定成protect 只能在類內或派生類內訪問。...

動態分配類物件與靜態分配類物件

動態分配類物件 就是使用運算子new來建立乙個類的物件,在堆上分配記憶體。靜態分配類物件 就是a a,由編譯器建立類物件,在棧上分配記憶體。1 動態分配類物件 把類的建構函式和析構函式設為protected屬性。類物件不能訪問,但是派生類可以繼承,也可以訪問。同時,建立create和destroy兩...