關于placement new 和 placement delete的重載,以及basic_string重載new()實例

關于placement new

在https://blog.csdn.net/qq_42604176/article/details/111997397中已經介紹了placement new的形式。
它的形式為new()/delete().我們將分配好內存的指針送入括號中,就完成了初步的調用了。
其實我們可以定義放任何的東西到()內部。只放一個指針的版本是的new()是標準庫先寫好給我們的。
我們可以重載operator new,并寫出多個版本,如:

Foo* pf = new(300,'c')Foo;	//注意,這里沒有傳入指針

前提是每一個版本的聲明都必須由獨特的參數列,其中第一個參數必須是size_t,這是因為當沒有()時,進行的是new Foo操作,Foo的大小會被傳進operator new中作為第一參數,Foo的大小是個size_t類型。所以我們寫的各種各樣的版本也必須遵循這個規則。第二第三參數等等可由自己設計。new()括號中的就是第二第三參數,他們可以指定placement arguments 為初值。
下面是實例:

class Foo {
public:Foo() {cout << "Foo::Foo()" << endl; };Foo(int) {cout << "Foo::Foo()" << endl; throw Bad();}	//這里故意拋出異常,用來測試 placement operator delete//【1】一般的operator new()的重載void* operator new(size_t size) {return malloc(size);}//【2】這個是標準庫已提供的placement new()的重載形式void* operator new(size_t size, void* start) {return start;}//【3】這個是我們重載的 placement new void* operator new(size_t size, long extra) {return malloc(size + extra);}//【4】這個也是我們重載的 placement newvoid* operator new(size_t size, long extra, char init) {return malloc(size + extra);}//【5】這個也是我們重載的,不過我們故意寫錯定義參數的類型void* operator new(long extra, char init) {return malloc(extra);}	//很顯然這個版本會報錯
};

關于placement delete

我們也可以重載placement operator delete,并對應著placement operator new寫出多個對應版本,但他們絕對不會被delete調用。
只有當new所調用的ctor拋出異常,才會調用這些重載版本的operator delete。
也就是說重載的placement operator delete是用來釋放未能成功創建的對象所占的內存。(正如我們所知,創建一個對象實際上是先申請空間,再調用構造函數。空間申請到了,但是對象卻沒構造出來,那么理所當然需要將空間釋放)
對應上面的四種版本的delete:

//【1】一般的 operator delete()的重載
void operator delete(void*,size_t)
{cout << "operator delete(void*,size_t)" << endl;
}
//【2】對應第二種
void operator delete(void*,void*)
{cout << "operator delete(void*,void*)" << endl;
}
//【3】對應第三種
void operator delete(void*,long)
{cout << "operator delete(void*,long)" << endl;
}
//【4】對應第四種
void operator delete(void*,long,char)
{cout << "operator delete(void*,long,char)" << endl;
}

侯捷老師給出了下面的示例,運行到第五種。我們可以發現,此時的構造函數調用的是第二種構造函數。在之前的定義中,我們在這里拋出了異常。
在這里插入圖片描述
接下倆便是這幾條語句的執行結果:
在這里插入圖片描述
如上所示,這些new都被重載了。所以才會打印信息。
按照道理,在構造函數拋出異常后,會調用自己重載的placement delete,打印信息。但在這里并沒有,這是編譯器的原因。

關于basic_string重載new()來擴充申請量

basic_string是標準庫里面的一個class,就是我們使用的字符串。
如下:

template<...>
class basic_string
{
private:struct Rep {...};...void release() {if(--ref == 0) delete this;}inline static void* operator new(size_t,size_t);inline static void operator delete(void*);inline static Rep* create(size_t);...
};

operator new的具體代碼如下:

template<class charT,class traits, class Allocator>
inline void* basic_string<charT,traits,Allocator>::Rep::
operator new(size_t s,size_t extra)
{return Allocator::allocate(s + extra * sizeof(charT));
}

如何使用看這兒:
這里我們把第二參數叫做extra。它的作用是,當使用者去創建一個字符串,如"hello",加上結束符一共6個字符。但是它在分配的時候還會分配extra個字符大小的空間。具體原因不做細究。

template<class charT,class traits,class Allocator>
inline basic_string<charT,traits,Allocator>::Rep*
basic_string<charT,traits,Allocator>::Rep::
create(size_t extra)
{extra = frob_size(extra + 1);Rep *p = new(extra)Rep;...return p;
}

它的placement delete重載之后則長這樣:

template<class charT,class traits,class Allocator>
inline void basic_string<charT,traits,Allocator>::Rep::
operator delete(void* ptr)
{Allocator::deallocate(ptr,sizeof(Rep) + reinterpret_cast<Rep*>(ptr)->res * sizeof(charT));
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/377367.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/377367.shtml
英文地址,請注明出處:http://en.pswp.cn/news/377367.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

cwc云萊特鏈_CWC的完整形式是什么?

cwc云萊特鏈CWC&#xff1a;工作條件的改變 (CWC: Change in Working Conditions) CWC is an abbreviation of "Change in Working Conditions". CWC是“工作條件更改”的縮寫 。 It is an expression, which is commonly used in the Gmail platform. In a particu…

在eclipse中創建web項目(非myeclipse)

在eclipse中創建web項目(非myeclipse) 在eclipse中如何創建dynamic web project項目 本文的演示是從本地文件創建dynamic web project&#xff0c;從svn檢出的同時創建dynamic web project于此類似。我們推薦使用解壓版的tomcat6.x版本&#xff0c;來作為服務器。可以到http://…

opengl glut 編譯

新建工程glut dll工程&#xff0c;本來想創建lib,工程的&#xff0c;但是想起來&#xff0c;gl是狀態機機制。dll方便資源共享等。 添加兩個include目錄 各種手機電腦平臺&#xff0c;網絡多媒體開發,mmsplayer&#xff0c;QQ514540005 然后將目錄下的lib/glut下面所有的.c文件…

劃分數據集代碼(按照4:1的比例)以及根據各自文件名寫入txt文件

會將圖片分到兩個文件夾中&#xff1a; #include <opencv2/opencv.hpp> #include "opencv2/features2d.hpp" #include <vector> #include <algorithm> #include <iostream> #include "windows.h" #include <stdio.h> #incl…

bpo是什么意思_BPO的完整形式是什么?

bpo是什么意思BPO&#xff1a;業務流程外包 (BPO: Business Process Outsourcing) BPO is an abbreviation of Business process outsourcing. It is a convention of a company to another company which is an external provider of services or business operations process…

在進行 ASP.NET 開發時,有時候需要對頁面輸出的最終 HTML 源代碼進行控制

在進行 ASP.NET 開發時&#xff0c;有時候需要對頁面輸出的最終 HTML 源代碼進行控制&#xff0c;是頁面的 render 方法中很容易實現這個功能。下面就是一個實現的方法&#xff0c;注釋都在代碼中。 [c-sharp] view plaincopy <% Page Language"C#" %> <% …

FireFox插件SQLite Manager的使用

最近幾天開始高IOS數據庫來著&#xff0c;一開始就CoreData的學習&#xff0c;結果高了一天沒有一點進展。 沒法&#xff0c;還是先老實代碼著吧&#xff0c;不過用的火狐插件可視化數據庫的操作也是不錯的似乎。 網上搜了搜用法&#xff0c;還真沒找到有什么的&#xff0c;最后…

簡單的數據增強代碼(C++與opencv)

包括了圖片批量平移、旋轉、以及像素變換 #include <opencv2/opencv.hpp> #include "opencv2/features2d.hpp" #include <vector> #include <algorithm> #include <iostream> #include "windows.h" #include <stdio.h> #in…

aes模式_AES的完整形式是什么?

aes模式AES&#xff1a;高級加密標準 (AES: Advanced Encryption Standard) AES is an abbreviation of Advanced Encryption Standard, also known by its original name Rijndael. It is an arrangement of standard for the encryption of electronic data set up by the U.…

IOS ----UIButton用法詳解

這段代碼動態的創建了一個UIButton,并且把相關常用的屬性都列舉了.希望對大家有用. //這里創建一個圓角矩形的按鈕UIButton *button1 [UIButton buttonWithType:UIButtonTypeRoundedRect];// 能夠定義的button類型有以下6種&#xff0c;// typedef enum {// UIButtonTypeCusto…

針對一個class寫出它的內存管理池以及總結出allocator類(三個版本)

目錄示例版本1&#xff1a;per-class allocator,1示例版本2&#xff1a;per-class allocator,2最終版本&#xff1a;static allocator針對版本三進行macro如果我們不針對對象做內存管理&#xff0c;那么我們每次進行Foo* p new Foo(x);時總是會調用malloc函數。 盡管malloc函數…

kotlin 第一個程序_Kotlin程序添加兩個矩陣

kotlin 第一個程序Given two matrices, we have to add them. 給定兩個矩陣&#xff0c;我們必須將它們相加。 Example: 例&#xff1a; Input:matrix 1:[2, 3][4, 5][7, 1]matrix 2:[4, 6][9, 0][7, 6]Output:[6, 9][13, 5][14, 7] 在Kotlin中添加兩個矩陣的程序 (Progra…

ubuntu 切換用戶的命令[shell, linux]

使用ubuntu過程中免不了和shell(終端)打交道, 也不可避免在各種用戶之間進行切換, 從而實現對各帳戶的管理, 這個就涉及到了一個比較基礎又很重要的工作,怎么樣切換用戶, 對于LINUX老鳥來說,這個根本不值不提的東東卻讓新手撓頭不已, 現在給出普通用戶和超級用戶切換的命令(附圖…

曲苑雜壇--修改數據庫名和文件組名

/* 該腳本示例如何完整的修改一個數據庫的名稱. 數據庫為原名稱為DB_BEIJING&#xff0c;需要修改成DB_SHANGHAI nzperfect 2012.12.19 */--判斷是否存在同名的數據庫&#xff0c;以防止誤刪除 USE master GO IF EXISTS (SELECT name FROM sys.databases WHERE name NDB_BEIJI…

關于new handler與default、delete關鍵字

在https://blog.csdn.net/qq_42604176/article/details/111638568的operate_new源代碼長啥樣中談到過new handler。 當operator new不能夠分配出申請的內存時&#xff0c;會拋出bad_alloc 異常。有的編譯器會返回0. 當定義成new(nothrow) Foo&#xff1b;就不會拋異常&#xff…

模式匹配運算符–Shell

轉載&#xff1a;http://www.firefoxbug.net/?p722 Var/home/firefox/MyProgram/fire.login.name ${Variable#pattern}:如果模式匹配于變量值的開頭處&#xff0c;則刪除匹配的最短部分&#xff0c;并且返回剩下的部分 例子&#xff1a; [fire]$ echo ${Var#*/} [fire]$ home/…

河內塔問題_河內塔的Python程序

河內塔問題You are challenged for a challenge to find the number of moves required to move a stack of disks from one peg to another peg. Wait for a second, it sounds easy? Let’s find are what is going on and in this article, we are introducing a chapter o…

VC6、BC5、G2.9標準分配器一覽

目錄VC6標準分配器BC5標準分配器G2.9標準分配器VC6標準分配器 VCx中源碼可以在電腦路徑中找&#xff1a; [D:\Program Files\VisualStudio\Community\VC\Tools\MSVC\14.28.29333\include\xmemory] 不過太多了。大概在837行左右有關于allocator代碼。還是先看侯捷PPT上的吧。 …

【轉】shell 大括號、圓括號的使用

在這里我想說的是幾種shell里的小括號,大括號結構和有括號的變量&#xff0c;命令的用法&#xff0c;如下&#xff1a; PHP 代碼:1.${var} 2.$(cmd) 3.()和{} 4.${var:-string},${var:string},${var:string},${var:?string} 5.$((exp)) 6.$(var%pattern),$(var%%pattern),$(va…

css clear屬性_CSS中的clear屬性

css clear屬性CSS | 清除財產 (CSS | clear Property) We know so much about float property and how it is used for styling our web pages. If you do not remember the float property, lets help jog your memory. The float property is used to set the elements in a …