gpt4 book ai didi

c++ - 是否可以对全局运算符 `new` 和 `delete` 执行回调?

转载 作者:行者123 更新时间:2023-11-30 01:58:23 42 4
gpt4 key购买 nike

这是我正在做的:

#include <iostream>

using namespace std;

class Test
{
public:
int i;
Test();
Test(int x);
~Test();

static void operator delete(void * t);
};

Test::Test() : i(1) { cout << "constructing" << endl; }

Test::Test(int x) : i(x) { cout << "constructing w/ arg" << endl; }

Test::~Test() { cout << "destructing" << endl; }

Test::operator delete(void *self)
{
cout << "deleting" << endl;
((Test *) t)->~Test(); // call destructor since it isnt called otherwise
::delete(t); // actually delete memory
}

template <typename T> // too lazy to figure out correct type
void callback(Test *t, T fn)
{
(fn)(t); // delete operator is implicitly static so this syntax is correct
}

int main()
{
Test *t = new Test();
callback(t, &Test::operator delete); // deletes t
}

我注意到,除非 operator delete 为我的类重载,否则前面的代码片段将无法编译。如果包含它,它将按预期编译和工作(首先调用构造函数,然后重载 delete,然后是析构函数,每个恰好一次)。

我考虑过传递全局删除运算符 ::operator delete,但这也不起作用(我收到未解析的重载函数调用)。我可以在不尝试获取其地址的情况下调用它。

如果不定义我自己的 ::operator delete 重载,我能做些什么吗?

我知道基本上没有任何用例需要我使用这样的东西。我知道 ::operator delete 不是一般用途的东西,它不会调用析构函数....

最佳答案

全局运算符 new/delete 是重载函数 - 您需要转换为正确的函数指针类型:

callback(t, static_cast<void(*)(void*)>(::operator delete));

编辑:我正在扩展我的答案以澄清一些事情。

的确,全局operator delete 不调用析构函数。它只是负责将内存返回到运行时的释放函数。调用析构函数是 delete expression 的工作:

Delete 表达式首先调用它的指针参数指向的对象(或多个对象,如果我们使用数组形式)的析构函数,然后调用释放函数(如果被删除的指针是类类型,它会在首先查找该类的范围,如果找不到则调用全局类)。

另一个需要注意的重要事项是在 delete 表达式中使用 void* 指针是未定义的行为,这就是您在重载中所做的:

cout << "deleting" << endl;
((Test *) self)->~Test();
::delete(self); // this is delete expression using void*, UB

您没有调用全局 operator delete,为此您需要调用 ::operator delete(t);。您有一个删除表达式,范围解析运算符只是告诉它不要在类范围内查找释放函数。

如果将其更改为此 ::delete( (Test*) self); 您将看到 destructing 被打印两次,再次是 UB。

总而言之,不要在operator delete里面调用析构函数,这不是它的工作。

关于c++ - 是否可以对全局运算符 `new` 和 `delete` 执行回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17558759/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com