是否可以对全局运算符“new”和“delete”执行回调
Is it possible to perform callbacks to the global operators `new` and `delete`?
我正在做的是:
#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表达式首先调用其指针参数指向的对象(如果我们使用数组形式,则为一个或多个对象)的析构函数,然后调用释放函数(如果要删除的指针是类类型的,则它首先在该类的作用域中查找它,如果找不到,则调用全局函数)。
另一个需要注意的重要事项是,在delete表达式中使用void*
指针是未定义的行为,这就是您在重载中所做的:
cout << "deleting" << endl;
((Test *) self)->~Test();
::delete(self); // this is delete expression using void*, UB
您不是在调用全局operator delete
,因此您需要说::operator delete(t);
。您有一个delete表达式,作用域解析运算符只是告诉它不要在类作用域内查找解除分配函数。
如果您将其更改为此::delete( (Test*) self);
,您将看到destructing
被打印两次,再次是UB。
总而言之,不要在operator delete
内部调用析构函数,这不是它的工作。
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 执行函数时导致崩溃的变量
- 运算符C++ "delete []"仅删除 2 个前值
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在没有信号的情况下从C++执行QML插槽
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 为什么泄漏内存比在动态数组上执行 delete[] 慢
- 继承类上的运算符new和delete.操作员删除未执行
- Sqlite3/C++在不更改数据库大小的情况下执行DELETE语句
- 是否可以对全局运算符“new”和“delete”执行回调
- 执行"delete this"时缺少虚拟析构函数
- c++,最快的STL容器,用于递归地执行{delete[begin], insert[end]和对整个数组内容求和}
- 如果在成员函数中执行"delete this;",会发生什么情况?
- 当delete my_object;执行?是否所有其他内存都被sizeof(MyClass)向左移动