如何覆盖C ++中的删除行为? [英] How should overriding delete in C++ behave?

查看:92
本文介绍了如何覆盖C ++中的删除行为?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到的问题是,据我所知,delete操作符应该是一个静态函数,但有时编译器(VC ++)似乎将其视为动态。

The problem I'm running into is that as far as I know the delete operator should be a static function but sometimes the compiler (VC++) seems to be treating it as dynamic.

给定:

class Base
{
public:
  void* operator new(size_t size) { /* allocate from custom heap */ }
  void operator delete(void *p) { customFree(p, sizeof(Base)); }

  Base() {}
  virtual ~Base() {}
};

class Derived: public Base
{
public:
  void* operator new(size_t size) { /* allocate from custom heap */ }
  void operator delete(void *p) { customFree(p, sizeof(Derived)); }

  Derived() {}
  virtual ~Derived() {}
}

我看到的情况是删除基本指针将导致调用 Derived :: opeator delete。

What I see happening is that deleting the base pointer will result in call to Derived::opeator delete.

Base *p = new Derived();
delete p; //calls Derived::operator delete



如果我没有定义ANY destructors 然后我得到我期望发生:Base :: operator delete被调用。这似乎发生了,因为当定义析构函数时,编译器在 vtable 中插入一个称为标量删除析构函数那么该函数将调用 Derived :: delete

If I don't define ANY destructors then I get what I expected to happen: Base::operator delete is called. This seems to be happening because the compiler is inserting a function called 'scalar deleting destructor into the vtable when a destructor is defined. Then that function will call Derived::delete.

所以我有问题:
1)这是标准行为吗?
2)何时应该使用

So I have to questions: 1) Is this standard behavior? 2) When should I be using

void operator delete( void *, size_t );

vs。

void operator delete( void * );

如果上述是标准行为?

推荐答案

这当然是标准行为。如果使用派生类的操作符new,还将使用其运算符删除(还要注意,即使您没有明确地告诉编译器这些函数是静态的,它们也是 声明这样)。可能有一个淘气的情况,你在派生类中有一个运算符new,但是相应的运算符delete在基类中。我认为这是有效的,但我会避免。依靠基本操作符删除,而在派生类中定义自己的操作符new将不可避免地导致麻烦。

It is certainly Standard Behavior. If the derived class's operator new was used, its operator delete will also be used (also note even though you do not explicitly tell the compiler those functions are static, they are implicitly declared so). There might be the naughty case where you have an operator new in the derived class, but the corresponding operator delete is in the base class. I think that's valid, but i would avoid that. Relying on the base operator delete, while defining ones own operator new in the derived class will inevitable cause trouble.


如果我没有定义ANY析构函数,那么我得到了我期望的结果:

If I don't define ANY destructors then I get what I expected to happen:

你会得到未定义的行为:)一切都会发生,包括你会期望的东西(错误)。删除指向另一个类型的对象的基本指针需要一个虚拟析构函数。隐式声明的析构函数不是虚拟的。

You will get undefined behavior :) Everything can happen, including something you would expect (wrongly). Deleting through a base pointer that points to an object of another type requires a virtual destructor. The implicitly declared destructor is not virtual.


何时应使用void operator delete(void *,size_t);

When should I be using void operator delete( void *, size_t );

如果希望在操作员删除中已知分配的大小。我写了这里的意思:
hl = zh_TW。如果你使用(从你重载的成员运算符内删除/ new)全局运算符new&删除得到你的内存并释放它,甚至malloc / free,你不需要那个大小信息。但它可能有助于记录目的。

If you want to have the size that was allocated known in the operator delete. I wrote about what it means here: http://stackoverflow.com/questions/377178/how-does-the-standard-new-operator-work-in-c#390585 . If you use (from within your overloaded member operator delete/new) the global operator new & delete to get your memory and release it, or even malloc / free, you don't need that size information. But it could be useful for logging purposes.

这篇关于如何覆盖C ++中的删除行为?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆