未找到匹配的运算符删除;如果初始化引发异常,内存将不会被释放

no matching operator delete found; memory will not be freed if initialization throws an exception

本文关键字:内存 异常 释放 初始化 运算符 如果 删除      更新时间:2023-10-16

我创建了一个BaseObject类,它覆盖了新的(和删除的(运算符,这样我就可以在应用程序的生命周期中记录创建和销毁的内存,这样我可以很容易地发现任何未释放的内存。

然而,我在编译时遇到了以下错误(但运行良好(:

resourcemanager.h(36(:警告C4291:"void*BaseObject::operator new(size_t,const char*,int(":未找到匹配的运算符delete;如果初始化引发异常,则不会释放内存

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__)

从我在互联网上看到的情况来看,问题是由于被覆盖的删除运算符需要匹配的签名。因此,在这种情况下,如果我在delete运算符中添加"const*char file,int line",它应该会起作用。但后来我遇到了另一个问题,因为我无法对任何对象调用delete,因为它找不到匹配的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);
};

来自cppreferencehttps://en.cppreference.com/w/cpp/language/new:

如果初始化因抛出异常而终止(例如,从构造函数(,如果新表达式分配了任何存储,则它调用适当的解除分配函数:对于非数组类型为CCD_ 1,用于数组类型的operator delete[]。查看解除分配函数如果新表达式使用CCD_ 3语法,否则,如果T是类类型,则在T的范围中查找它。如果失败的分配函数是常见的(非放置(,查找deallocation函数遵循中所述的规则delete表达式对于放置失败的新的、所有参数类型,除了第一个之外,匹配的解除分配函数的与放置new的参数相同。对deallocation函数是从作为第一个参数传递的分配函数,作为可选的CCD_ 6自变量(由于C++17(和CCD_,如果有的话,作为附加放置参数传递。如果没有找到解除分配函数,内存未解除分配

因此,在您的情况下,删除的匹配签名是:

  1. 剥去size
  2. 放置void* ptr
  3. 重复传递给CCD_ 10的参数

这导致:

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);
};

偏离主题:抽象不是C++中的关键字,这应该是一个编译错误。要使类抽象,请将函数定义为纯虚拟函数(将operator delete1作为其定义(。