我很好奇delete运算符怎么知道派生类的大小呼吁删除基址指针时,这里是一个小例子:如何从基指针中知道派生类的大小?
class IVariant
{
public:
virtual ~IVariant() = default;
virtual void print_value() = 0;
};
template<typename T>
class Variant: public IVariant {};
template<>
class Variant<int>: public IVariant
{
private:
int m_integer;
public:
Variant(int integer): m_integer(integer) {}
void print_value() override
{
printf("integer: %i\n", m_integer);
}
};
template<>
class Variant<double>: public IVariant
{
private:
double m_dbl;
public:
Variant(double val): m_dbl(val) {}
void print_value() override
{
printf("double: %g\n", m_dbl);
}
};
template<>
class Variant<std::string>: public IVariant
{
private:
std::string m_string;
public:
Variant(const std::string& string): m_string(string) {}
void print_value() override
{
printf("string: %s\n", m_string.c_str());
}
};
测试:
int main()
{
IVariant* int_var = new Variant<int>(100);
IVariant* dbl_var = new Variant<double>(100.0f);
IVariant* str_var = new Variant<std::string>("the value is 100\n");
int_var->print_value();
dbl_var->print_value();
str_var->print_value();
delete int_var;
delete dbl_var;
delete str_var;
}
delete运算符正确认识从基址指针单独的那个如此释放的4个字节,dbl_var = variant<double>
这样释放了8个字节,因此它释放了28个字节。
但它是如何知道的?新操作员是否存储大小为&的指针,然后删除操作员可以使用它来释放正确数量的字节?我知道这是怎么删除[]数组的作品,但我无法找到任何信息,当它来到派生类
这是实现定义的。您需要指定您想要了解哪些实现以获得有意义的答案。 –
总之,是的。堆分配具有已创建的每个对象的大小和类型信息。调用删除将进入查找表并释放给定对象的相应数量的字节。 – callyalater
标准库的'operator new'的默认堆内存分配器“知道”每个分配给您的指针拥有多少内存。它是负责清理的人员,在运行时已经正确地调用适当的析构函数。 – WhiZTiM