簡體   English   中英

如何將析構函數分配給指針?

[英]How to assign a destructor to a pointer?

我正在編寫一個 memory 管理庫,需要顯式調用析構函數,在我的設計中,我有一個指向 object 的析構函數方法的指針,我編寫如下代碼:

void (*p)() = foo.~Foo;

但我得到了

錯誤:無法將 'Foo::~Foo' 從類型 'void (Foo::)() noexcept' 轉換為類型 'void (*)()'

我嘗試了其他一些格式,例如void (Foo:: (*p))() noexcept = foo.~Foo; 但失敗了。

那么將析構函數分配給指針的正確方法是什么?

編輯:在運行時我的代碼不知道它在我的堆中是什么類型,所以我不能使用 foo.~Foo()。 我需要一個適合所有析構函數的生成指針,這可能嗎?

解決方案:使用模板包裝器

不允許使用析構函數的地址。

但是,您可以制作一個非常簡單的模板 function 並使用它來代替:

template<class T>
void destruct(const T* x) {
    x->~T();
}

現在,只需從以下位置獲取指針:

destruct<Foo>

您可以使用例如。 如果您需要綁定到實際的 object,請使用std::bind (或 lambda):

std::bind(&destruct<Foo>, foo_ptr);

請注意,一旦綁定,它就不能轉換為原始的 function 指針。

對不起,你不能。 您不能根據[class.dtor]/2 獲取析構函數的地址:

析構函數用於銷毀其 class 類型的對象。 不應采用析構函數的地址。 可以為constvolatileconst volatile object 調用析構函數。 constvolatile語義 ([dcl.type.cv]) 不適用於正在破壞的 object。 當派生最多的 object 的析構函數啟動時,它們停止生效。

我需要一個適合所有析構函數的生成指針,這可能嗎?

不它不是。 就像它不會與任何其他成員 function 一樣。

要在 object 上調用 function,您需要知道 object 的類型。

而且,由於您無法獲取析構函數的地址,因此您甚至無法在“數據庫”中存儲/注冊一個。 然而,正如 Paul 所展示的,您可以存儲一個函子來完成這項工作。 為每個正在使用的 object 注冊這些會有點難看,但是當您嘗試重新發明類型系統時會發生這種情況!

我強烈建議不要使用類型擦除(改用一些不錯的 inheritance 怎么樣?),不要自己調用析構函數。

請記住,析構函數當然是成員 function,因此您需要兩個指針:一個指向 object,一個指向成員 ZC1C425268E68385D1AB5074C17A94F4 的偏移量(在這種情況下為析構函數)。

要獲取對象的地址很簡單,只需使用std::addressof()

但是要獲得析構函數,您需要一個包裝器 function 來調用給定對象地址的析構函數,因為您不能獲取析構函數的地址。

所以使用像Herb Sutter建議的東西(感謝@LightnessRacesinOrbit 和@Croolman 的評論):

[](const void* x) { static_cast<const Foo*>(x)->~Foo(); }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM