c new運算子是如何呼叫建構函式的

2021-10-03 07:27:26 字數 2333 閱讀 8387

本文內容簡短,只為記錄下一次思考過程,事情起源於一句話,「new操作符會呼叫operator new分配記憶體再呼叫建構函式構造物件」,但最近再次看到這句話的時候越看越有疑問,怎麼樣呼叫建構函式??於是就帶著這個問題順便看下operator new和placement new的原始碼加深下印象了。

眾所周知建構函式是在例項化乙個類物件時呼叫,通常我們看到的建構函式是下面這樣用:

classa;

intmain()

上述幾種呼叫方式,不管是在棧上還是堆上例項化乙個類物件時,共同點都是記憶體的申請和類的構造是繫結在一起的。可以試想一下,既然new是先呼叫operator new再呼叫建構函式,那麼這個過程如果我們自己手動呼叫呢:

#include

using

namespace std;

class

aint a;};

intmain()

看起來是沒什麼問題,但實際結果呢?直接編譯出錯,報錯為:

錯誤:錯誤地使用了『a::a』

即使更改為顯示呼叫,仍然無法編譯通過:

int

main()

錯誤:不能直接呼叫建構函式『a::a』

到這裡就產生了深深的疑問,建構函式不能被顯示呼叫,那new是怎麼呼叫建構函式的?

另一方面,我們知道placement new就是在已分配記憶體上構造物件的,那麼placement new是如何只呼叫建構函式的?

class

aint a;};

intmain()

先來看下operator new和placement new的實現:

_glibcxx_weak_definition void

*operator

new(std::size_t sz) _glibcxx_throw (std::bad_alloc)

return p;

}

// default placement versions of operator new.

inline

void

*operator

new(std::size_t,

void

* __p) _glibcxx_use_noexcept

inline

void

*operator

new[

](std::size_t,

void

* __p) _glibcxx_use_noexcept

// default placement versions of operator delete.

inline

void

operator

delete

(void*,

void

*) _glibcxx_use_noexcept

inline

void

operator

delete

(void*,

void

*) _glibcxx_use_noexcept

可以看到,operator new只是對malloc的一些封裝,而placement new則是什麼都沒做只是把指標返回。至此也基本可以猜到答案了,答案就是編譯器自動呼叫的,想一下也必然是這樣,new是個運算子不是函式,運算子是一種告訴編譯器執行特定的數學或者邏輯操作的符號,又何來定義之說。

下面是一些參考:

thus, for a class type t, a new-expression such as:

pt =

new t;

translates more-or-less into something like:

pt =

static_cast

(operator

new(

sizeof

(t)));

pt->t(

);

[1] calling constructors with placement new -dr.dobb』s

[2] when is the constructor called by 『new』 operator in c++

[3] 原始碼

[4] 原始碼

C new 運算子 用法總結

1.分配記憶體初始化標量型別 如 int 或 double 在型別名後加初始值,並用小括號括起,c 11中也支援大括號。int pi new int 6 double pd new double 9.99 c 11中,支援以下寫法 int pi new int double pd new doubl...

函式呼叫運算子

14.34定義乙個函式物件類,令其執行if then else的操作 該型別的呼叫運算子接受三個引數,它首先檢查第乙個形參,如果成功返回第二個引數的值 如果不成功返回第三個形參的值。includeusing namespace std class if then else int main 14.3...

函式呼叫運算子

struct absint 這個類定義了操作 函式呼叫運算子,它負責接受乙個int型別的實參,然後返回該實參的絕對值。呼叫 int i 42 absint absobj 含有函式運算子的物件 int ui absobj i 將i傳遞給absobj.operator class printstring...