运算符"delete this"究竟是怎么做的呢?
How the operator "delete this" do exactly?
我刚刚测试了有关 "delete this" 的运算符。使用 handle 系统调用 "new/delete" 将丢失一个覆盖删除函数调用。
句柄函数如下:
inline void* operator new(size_t size)
{
void* p = ::malloc( size );
fprintf( stderr, "new size %ld: %p\n", size, p );
return p;
}
inline void* operator new[]( size_t size )
{
void* p = ::malloc( size );
fprintf( stderr, "new size[] %ld: %p\n", size, p );
return p;
}
inline void operator delete(void* p)
{
fprintf( stderr, "delete: %p\n", p );
::free(p);
}
inline void operator delete[](void* p)
{
fprintf( stderr, "delete []: %p\n", p );
::free(p);
}
并测试 class:
class A
{
public:
A() : a(NULL)
{
printf( "A construct\n" );
a = new int[100];
}
~A()
{
printf( "A destruct \n" );
freeA();
}
void freeA()
{
if ( a ) { delete [] a; a = NULL; }
}
void release()
{
delete this;
}
private:
int* a;
};
当我打电话时
A* a = new A();
a->release();
结果是:
new size 8: 0x5642fc1c4e70
A construct
new size[] 400: 0x5642fc1c52a0
A destruct
delete []: 0x5642fc1c52a0
缺少关于 A(0x5642fc1c4e70) 的删除调用,为什么?
我刚发现问题:使用内联,运算符 delete(void* p) 根本无法调用。但是 delete[](void* p) 可以。
现在我将关闭它。
https://timsong-cpp.github.io/cppwp/replacement.functions#3
The program's definitions are used instead of the default versions
supplied by the implementation ([support.dynamic]). Such replacement
occurs prior to program startup ([basic.def.odr], [basic.start]). The
program's declarations shall not be specified as inline. No diagnostic
is required.
这是规则。不允许内联。这就是您缺少一个删除的原因,它在没有内联说明符的情况下也能工作。
我运行将你的代码设置在c++14以下,你的delete
运算符可以被正确调用。
https://onlinegdb.com/S1zAgzXbB
但是,运行宁超过版本 c++14(包括 c++14),然后需要将代码从 inline void operator delete(void* p)
更改为 inline void operator delete(void* p,std::size_t sz)
或删除 inline
关键字。那么您的代码将 运行 正确
https://onlinegdb.com/BJ3hMz7WH
希望对你有所帮助
既然你已经定义了一个析构函数,那么就不需要定义释放函数了。直接在实例的指针上使用 delete
而不是
A* a = new A();
a->release();
你会
A* a = new A();
delete a;
删除 a 将调用 ~A() 析构函数
我刚刚测试了有关 "delete this" 的运算符。使用 handle 系统调用 "new/delete" 将丢失一个覆盖删除函数调用。
句柄函数如下:
inline void* operator new(size_t size)
{
void* p = ::malloc( size );
fprintf( stderr, "new size %ld: %p\n", size, p );
return p;
}
inline void* operator new[]( size_t size )
{
void* p = ::malloc( size );
fprintf( stderr, "new size[] %ld: %p\n", size, p );
return p;
}
inline void operator delete(void* p)
{
fprintf( stderr, "delete: %p\n", p );
::free(p);
}
inline void operator delete[](void* p)
{
fprintf( stderr, "delete []: %p\n", p );
::free(p);
}
并测试 class:
class A
{
public:
A() : a(NULL)
{
printf( "A construct\n" );
a = new int[100];
}
~A()
{
printf( "A destruct \n" );
freeA();
}
void freeA()
{
if ( a ) { delete [] a; a = NULL; }
}
void release()
{
delete this;
}
private:
int* a;
};
当我打电话时
A* a = new A();
a->release();
结果是:
new size 8: 0x5642fc1c4e70
A construct
new size[] 400: 0x5642fc1c52a0
A destruct
delete []: 0x5642fc1c52a0
缺少关于 A(0x5642fc1c4e70) 的删除调用,为什么?
我刚发现问题:使用内联,运算符 delete(void* p) 根本无法调用。但是 delete[](void* p) 可以。 现在我将关闭它。
https://timsong-cpp.github.io/cppwp/replacement.functions#3
The program's definitions are used instead of the default versions supplied by the implementation ([support.dynamic]). Such replacement occurs prior to program startup ([basic.def.odr], [basic.start]). The program's declarations shall not be specified as inline. No diagnostic is required.
这是规则。不允许内联。这就是您缺少一个删除的原因,它在没有内联说明符的情况下也能工作。
我运行将你的代码设置在c++14以下,你的delete
运算符可以被正确调用。
https://onlinegdb.com/S1zAgzXbB
但是,运行宁超过版本 c++14(包括 c++14),然后需要将代码从 inline void operator delete(void* p)
更改为 inline void operator delete(void* p,std::size_t sz)
或删除 inline
关键字。那么您的代码将 运行 正确
https://onlinegdb.com/BJ3hMz7WH
希望对你有所帮助
既然你已经定义了一个析构函数,那么就不需要定义释放函数了。直接在实例的指针上使用 delete
而不是
A* a = new A();
a->release();
你会
A* a = new A();
delete a;
删除 a 将调用 ~A() 析构函数