進一步了解new操作符

2021-07-12 07:52:53 字數 2252 閱讀 1266

我們又了解new多少呢?

對於new:先進行空間分配,再進行呼叫建構函式。

在new與delete中的第二步,實際上都是呼叫乙個全域性函式operator new/delete對空間進行分配/**。

在這個全域性建構函式中::operator new 有6個過載,其中有三個是關於陣列空間的分配。

如下:

void *operator new(std::size_t count) throw(std::bad_alloc);               // 一般的版本

void *operator new(std::size_t count,new const std::nothrow_t&) throw(); // 記憶體分配失敗不會丟擲異常

void *operator new(std::size_t count, void *ptr) throw(); //placement 版本

void *operator new(std::size_t count)  throw(std::bad_alloc);

void *operator new(std::size_t count, const std::nothrow_t&) throw();

void *operator new(std::size_t count, void *ptr) throw();

對於一般版本,為了相容早期new而不丟擲異常的版本 ,我們已經用的很熟練了,我們只談一談placment new 版本。

區分new 操作符與operator new 函式是十分重要的,對於new操作符,我們不可以過載所以new操作符的行為是確定的,而operator new是可以進行過載的,對其進行替換的 。但對於placement new 版本,在c++標準中已經明令禁止我們去過載這個版本,對於其它版本我們可以任意的去替換掉(說是這麼說但實際上並不贊同這樣做)。

為什麼c++嚴禁我們去過載這個placement new 這個函式呢,palcement new 與其它過載版本不同它實際上並不會分配任何空間,僅僅返回乙個可能指向空間的指標。

因此我們不能對placemen newt進行delete操作。

可能有人會問對於placement new有什麼作用?

我們在建立乙個物件的時候,我們可能不想給它初始化,我們希望遲一點初始化,這時候,而我們提前對它的初始化就是十分浪費效率的。

我們就可以這樣做

a *number0 = static_cast(::operator new(sizeof(a)));

new(number0)a();

對於operator new(size_t);實際上與memory.h標頭檔案中的malloch函式效果是一樣的的。

通常對placement new也搭配一些其它操作,一般來說這個是必要的,我們必須對乙個類物件進行析構,不過直接對乙個物件進行析構十分不妥的,我們需要對這個析構進行一下封裝。

實際上,對於乙個類而不是語言內嵌型別,對於乙個new與delete的操作實際上是分成三步的,多了一步,我們在進行operator new 呼叫之前會先查詢class內是否有這個operator new 的過載,如果有我們會呼叫class中的過載版本,有一點就算我們把operator new 宣告為私有類成員,編譯器也只會提示乙個類成員不可呼叫,也不會呼叫全域性的operator new。

我們在開始說placement new 過載是明令禁止的,但這個要求僅限於全域性,我們在類中仍可以定義乙個「placement new」。

還有一點,對於類內過載的operator new/delete是靜態成員函式, 因為他用不到this指標。所以operator new/delete是可以被繼承的,

關於陣列的說明:

!只有一點

我們對於陣列的分配方法

a *number1 = static_cast(::operator new(sizeof(a)*2));

a *number2 = new a[2];

第二種相對於第一種可能會略微增加記憶體。

關於operator new我們可能面臨這樣乙個錯誤,當我們無法知道乙個類是否已經過載operaotr的時候,我們就面臨著乙個很危險的行為,我們無法準確的對這個類進行異常的判斷此時我們必須將所有的operator new都使用全域性版本。

一般的來說我們在過載operator new 的時候一般也會過載operator delete 如果乙個類的operator new 分配失敗則,這個類將呼叫operator delete 進行**。

進一步了解Makefile

mkdir p add src 一層一層建立目錄。touch add makefile 建立 makefile include 目錄中存放標頭檔案。scripts 存放指令碼檔案。存放方式 按照核心管理原始碼來管理。為什麼學習makefile?編譯大型專案 讀懂別人的開源 找到程式入口 看專案的順序...

進一步了解Spring Cloud

spring cloud是 系列框架的有序集合。它利 spring boot的開發便利性巧妙地簡化了分布式系統基礎設施的開發,如服務發現註冊 配置中 訊息匯流排 負載均衡 斷路器 資料監控等,都可以 spring boot的開發 格做到 鍵啟動和部署。spring cloud並沒有重複製造輪 它只是...

進一步了解pip

在python中,安裝第三方模組,是通過包管理工具pip完成的。當我們試圖載入乙個模組時,python會在指定的路徑下搜尋對應的.py檔案,如果找不到,就會報錯。預設情況下,python直譯器會搜尋當前目錄 所有已安裝的內建模組和第三方模組,搜尋路徑存放在sys模組的path變數中 import s...