只能動態 靜態分配類物件

2021-08-06 06:57:02 字數 3145 閱讀 7231

// 只能動態分配類物件.cpp : 定義控制台應用程式的入口點。

//#include "stdafx.h"

#include using namespace std;

/********************只在堆上建立***********************/

//把析構函式設定為私有即可,但是這樣的話以它為基類的派生類就不能訪問析構函式來釋放資源了

//因此設定成protect 只能在類內或派生類內訪問。現在可以只在對上分配類物件了,但是用了new之後卻要單獨呼叫destrory來釋放,不規整;

//把建構函式也設定成protected,在public新建乙個建立的函式。為啥要是static,因為不是的話你都不知道怎麼去建立新物件了。。因為不能靜態建立,只能直接通過類來造。

class dui;

void destory()

private:

protected:

dui::dui();

~dui();

};/********************只在堆上建立***********************/

/********************只在棧上建立***********************/

//不讓用new就可以了,把new放在private裡面

class zhan // 注意函式的第乙個引數和返回值都是固定的 注意過載格式

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

protected:

};/********************只在棧上建立***********************/

int _tmain(int argc, _tchar* argv)

**

昨天乙個同學去網易面試c++研發,問到了這麼乙個問題:如何限制乙個類物件只在棧(堆)上分配空間?

一般情況下,編寫乙個類,是可以在棧或者堆分配空間。但有些時候,你想編寫乙個只能在棧或者只能在堆上面分配空間的類。這能不能實現呢?仔細想想,其實也是可以滴。

在c++中,類的物件建立分為兩種,一種是靜態建立,如a a;另一種是動態建立,如a* ptr=new a;這兩種方式是有區別的。

1、靜態建立類物件:是由編譯器為物件在棧空間中分配記憶體,是通過直接移動棧頂指標,挪出適當的空間,然後在這片記憶體空間上呼叫建構函式形成乙個棧物件。使用這種方法,直接呼叫類的建構函式。

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

那麼如何限制類物件只能在堆或者棧上建立呢?下面分別進行討論。

容易想到將建構函式設為私有。在建構函式私有之後,無法在類外部呼叫建構函式來構造類物件,只能使用new運算子來建立物件。然而,前面已經說過,new運算子的執行過程分為兩步,c++提供new運算子的過載,其實是只允許過載operator new()函式,而operatornew()函式只用於分配記憶體,無法提供構造功能。因此,這種方法不可以。

當物件建立在棧上面時,是由編譯器分配記憶體空間的,呼叫建構函式來構造棧物件。當物件使用完後,編譯器會呼叫析構函式來釋放棧物件所佔的空間。編譯器管理了物件的整個生命週期。如果編譯器無法呼叫類的析構函式,情況會是怎樣的呢?比如,類的析構函式是私有的,編譯器無法呼叫析構函式來釋放記憶體。所以,編譯器在為類物件分配棧空間時,會先檢查類的析構函式的訪問性,其實不光是析構函式,只要是非靜態的函式,編譯器都會進行檢查。如果類的析構函式是私有的,則編譯器不會在棧空間上為類物件分配記憶體。因此,將析構函式設為私有,類物件就無法建立在棧上了。**如下:

class a  

void destory()

private:

~a(){}

};

試著使用a a;來建立物件,編譯報錯,提示析構函式無法訪問。這樣就只能使用new操作符來建立物件,建構函式是公有的,可以直接呼叫。類中必須提供乙個destory函式,來進行記憶體空間的釋放。類物件使用完成後,必須呼叫destory函式。

無法解決繼承問題。如果a作為其它類的基類,則析構函式通常要設為virtual,然後在子類重寫,以實現多型。因此析構函式不能設為private。還好c++提供了第三種訪問控制,protected。將析構函式設為protected可以有效解決這個問題,類外無法訪問protected成員,子類則可以訪問。

類的使用很不方便,使用new建立物件,卻使用destory函式釋放物件,而不是使用delete。(使用delete會報錯,因為delete物件的指標,會呼叫物件的析構函式,而析構函式類外不可訪問)這種使用方式比較怪異。為了統一,可以將建構函式設為protected,然後提供乙個public的static函式來完成構造,這樣不使用new,而是使用乙個函式來構造,使用乙個函式來析構。**如下,類似於單例模式

class a  

~a(){}

public:

static a* create()

void destory()

};

這樣,呼叫create()函式在堆上建立類a物件,呼叫destory()函式釋放記憶體。

只有使用new運算子,物件才會建立在堆上,因此,只要禁用new運算子就可以實現類物件只能建立在棧上。雖然你不能影響new operator的能力(因為那是c++語言內建的),但是你可以利用乙個事實:new operator 總是先呼叫 operator new,而後者我們是可以自行宣告重寫的。因此,將operator new()設為私有即可禁止物件被new在堆上。**如下:

class a  

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

void

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

public:

a(){}

~a(){}

};

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

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

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

c 中建立類的物件有兩種方式 1 靜態建立,例如 a a 靜態建立乙個類物件,就是由編譯器為物件在棧空間中分配記憶體。使用這種方法,是直接呼叫類的建構函式。2 動態建立,例如 a p new a 動態建立乙個類物件,就是使用new運算子為物件在堆空間中分配記憶體。這個過程分為兩步 第一步執行oper...

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

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