當前位置: 華文星空 > 知識

C++中什麽情況下需要多載new運算子?

2021-07-07知識

那是你見識太少了。問你兩個問題,不求你能回答,但至少求你能看的懂問題。

1. SIMD 中不少指令是要求數據對齊的,請問要是對齊要求超過了 malloc/new 預設的對齊了,你打算怎麽辦?

對齊版本的 operator new 多載了解一下?

void * operator new ( std :: size_t count , std :: align_val_t al );

2. new 申請不到記憶體時,在預設情況下,是會一個迴圈,不斷呼叫 std::get_new_handler 返回的函式指標,直到分配成功為止的。我覺得這也太坑了,頂多試三次就行了,你打算怎麽辦?

把你程式碼裏出現 new 的地方全一個一個替換掉麽?累死你。

你說用不到這個功能,那是因為都給你封裝在底層了,不需要來讓你操心了。

我跟你說,要是沒多載 new 這個功能,你連最基礎的 vector 都實作不了。

vector 最核心的需求是什麽?是要求記憶體分配和物件的構造之間能解耦、解分配和物件的析構之間能解耦。說人話,就是需要先用 allocator.allocate() 方法從分配器中提前分配出記憶體塊, 等推遲到合適的時候,才在這個記憶體塊上構造出物件

那些叫囂 100 行寫出的 vector,其實作都是根本不能用的,裏面全是用的 new T[]。

正規的寫法必須要用到 placement new —— 這是多載 new 的最機智的利用。

vector 的基本原理如下:

#include <new> #include <iostream> struct Foo { int i ; Foo ( int i ) : i ( i ) { std :: cout << "構造 " << i << std :: endl ; } ~ Foo () { std :: cout << "析構 " << i << std :: endl ; } }; int main () { std :: allocator < Foo > alloc ; Foo * p = alloc . allocate ( 3 ); std :: cout << "分配好緩沖區了" << std :: endl ; for ( int i = 0 ; i < 3 ; ++ i ) { std :: cout << "push_back 第 " << i << " 個元素" << std :: endl ; new ( p + i ) Foo ( i ); } for ( int i = 0 ; i < 3 ; ++ i ) { std :: cout << "pop_back 第 " << i << " 個元素" << std :: endl ; ( p + 2 - i ) ->~ Foo (); } alloc . deallocate ( p , 3 ); std :: cout << "釋放完緩沖區了" << std :: endl ; }

輸出:

分配好緩沖區了 push_back 第 0 個元素 構造 0 push_back 第 1 個元素 構造 1 push_back 第 2 個元素 構造 2 pop_back 第 0 個元素 析構 2 pop_back 第 1 個元素 析構 1 pop_back 第 2 個元素 析構 0 釋放完緩沖區了

你以為 placement new 是 C++ 為其特殊設計的語法?

不是的,placement new 只是一個函式呼叫而已。它只不過是:

void * operator new ( std :: size_t , void * p ) { return p ; }