假设我有以下代码(https://godbolt.org/z/MW4ETf7a8):
犃
#include <iostream>
struct X{
void* operator new(std::size_t size)
{
std::cout << "new X\n";
return malloc(size);
}
void operator delete(void* ptr)
{
std::cout << "delete X\n";
return free(ptr);
}
virtual ~X() = default;
};
struct ArenaAllocatedX : public X {
void* operator new(std::size_t size)
{
std::cout << "new ArenaAllocatedX\n";
return malloc(size);
}
void operator delete(void* ptr)
{
std::cout << "delete ArenaAllocatedX\n";
return free(ptr);
}
};
主程序
int main() {
X* x1 = new X();
delete x1;
X* x2 = new ArenaAllocatedX ();
delete x2;
}
使用 GCC 10.3.1,
x1
调用的new
和delete
操作符class X
,同时x2
调用class ArenaAllocatedX
。
我理解它将如何选择new
运算符,因为它的右边有实际的类名,但我不明白delete
在被指向时如何为子类选择运算符X*
。
new
/运算符是否被delete
视为虚拟表内的函数(我使用转储了 VTablegcc -f-dump-lang-class
但没有看到任何删除运算符)?
VTable转储:
Vtable for X
X::_ZTV1X: 4 entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI1X)
16 (int (*)(...))X::~X
24 (int (*)(...))X::~X
Class X
size=8 align=8
base size=8 base align=8
X (0x0x7f38cd807780) 0 nearly-empty
vptr=((& X::_ZTV1X) + 16)
Vtable for ArenaAllocatedX
ArenaAllocatedX::_ZTV15ArenaAllocatedX: 4 entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI15ArenaAllocatedX)
16 (int (*)(...))ArenaAllocatedX::~ArenaAllocatedX
24 (int (*)(...))ArenaAllocatedX::~ArenaAllocatedX
Class ArenaAllocatedX
size=8 align=8
base size=8 base align=8
ArenaAllocatedX (0x0x7f38cd848680) 0 nearly-empty
vptr=((& ArenaAllocatedX::_ZTV15ArenaAllocatedX) + 16)
X (0x0x7f38cd807cc0) 0 nearly-empty
primary-for ArenaAllocatedX (0x0x7f38cd848680)
C++ 如何选择delete
在所提供的代码中使用哪个运算符?