c++ - 找不到匹配的运算符删除;如果初始化抛出异常,内存将不会被释放
问题描述
我创建了一个覆盖新(和删除)运算符的 BaseObject 类,因此我可以在应用程序生命周期中创建和销毁内存时记录内存,使我可以轻松发现任何未释放的内存。
但是,编译时出现以下错误(但运行良好):
resourcemanager.h(36): 警告 C4291: 'void *BaseObject::operator new(size_t,const char *,int)': 找不到匹配的运算符删除;如果初始化抛出异常,内存将不会被释放
baseobject.h(8):注意:参见“BaseObject::operator new”的声明
我的 BaseObject 类如下所示:
class BaseObject
{
public:
void* operator new(size_t size, const char* file, int line);
void* operator new[](size_t size, const char* file, int line);
void operator delete(void* ptr);
void operator delete[](void* ptr);
};
#define MY_NEW new(__FILE__, __LINE__)
#define MY_DELETE delete(__FILE__, __LINE__)
从我在互联网上阅读的内容来看,问题是由于被覆盖的删除运算符需要匹配的签名。所以在这种情况下,如果我将“const *char file, int line”添加到删除运算符,它应该可以工作。但是后来我遇到了另一个问题,因为我无法在任何对象上调用 delete,因为它没有找到匹配的删除运算符(它现在必须将文件和行作为输入)。在这种情况下,使用上面的 MY_DELETE 宏不起作用,因为 delete 不能使用这样的参数。
在这里几乎是不知所措。
编辑:
解决方案不是立即显而易见的。添加具有与新函数相同的额外参数的重写删除函数是不够的,因为这会产生“没有非放置删除运算符”的问题。这反过来可以通过添加非放置删除运算符来解决。所以,这个类现在看起来像这样(并且它正在工作):
class BaseObject
{
public:
void* operator new(size_t size, const char* file, int line);
void* operator new[](size_t size, const char* file, int line);
// Placement delete functions, matching overridden new functions
void operator delete(void* ptr, const char* file, int line);
void operator delete[](void* ptr, const char* file, int line);
// Non-placement delete functions
void operator delete(void* ptr);
void operator delete[](void* ptr);
};
解决方案
从 cppreference https://en.cppreference.com/w/cpp/language/new:
如果初始化通过抛出异常终止(例如从构造函数),如果 new-expression 分配了任何存储,它调用适当的释放函数:
operator delete
对于非数组类型,operator delete[]
对于数组类型。如果 new-expression 使用语法,则在全局范围内查找释放函数::new
,否则在 的范围内查找T
,如果T
是类类型。如果失败的分配函数是通常的(非放置),则查找释放函数遵循删除表达式中描述的规则。对于一个失败的placement new,匹配解除分配函数的所有参数类型,除了第一个,必须与placement new 的参数相同。对解除分配函数的调用是先前从分配函数获得的值,作为第一个参数传递,对齐作为可选alignment
参数传递(C++17 起),placement_params
如果有的话,作为附加放置参数传递。如果没有找到释放函数,则不会释放内存。
因此,在您的情况下,删除的匹配签名是:
- 剥离
size
- 放在
void* ptr
它的位置 - 重复传递给的参数
operator new
。
这将导致:
class BaseObject
{
public:
void* operator new(size_t size, const char* file, int line);
void* operator new[](size_t size, const char* file, int line);
void operator delete(void* ptr, const char* file, int line);
void operator delete[](void* ptr, const char* file, int line);
};
题外话:abstract 不是 C++ 中的关键字,这应该是编译错误。要使类抽象,请将函数定义为纯虚拟(通过将= 0
其作为定义)。
推荐阅读
- python - 运行“python manage.py makemigrations”命令给我语法错误
- python - 如何在 Django 中使用 form.cleaned_data.get() 将数据从视图传递到成功模板?
- python - 如何更改表格中特定行和列的颜色?
- javascript - 使用逻辑运算符和另一个数组过滤新数组
- phpmailer - phpmailer SMTP 错误“未接受数据”和“检查是否连接时捕获 EOF”
- python - Python Key 错误 json.loads 带括号
- android - AlertDialog.Builder 重置密码按钮不起作用.Android Studio
- javascript - 有什么方法可以访问 AudioWorkletProcessor 中的 AnalyserNode?
- flask - 数据尚未插入通过 WTForms 收集的数据库
- r - 如何解释 R 中随机效应模型的模型输出?