2010-05-03 68 views
3

我碰到这条线是斯特劳斯An operator function must either be a member or take at least one argument of a user-defined type (functions redefining the new and delete operators need not).重载新,删除C++

不要操作new和operator delete采取用户定义类型作为其参数之一? 这是什么意思,我失去了一些东西在这里

回答

3

可以重载正常的全球new操作,所有类,如果你愿意的话添加功能(例如日志或泄漏检测),但有没有办法叫老定义了new运营商,因此您可能会被卡住在重新定义的operator new之内调用malloc()以实际获取您需要的内存。

+0

这是否会超载(甚至重写),那么会有一个方法来调用原有的全球'new'。这不是超载。 – wilhelmtell 2010-05-03 05:20:24

+1

它实际上是更换和不超载,所以一旦你提供你自己的'new' /'delete'没有办法叫“原始”的。 – 2010-05-03 05:45:03

5

来自Stroustrup的报价显然适用于运营商超载。 C++语言仅支持用户定义类型的运算符重载。这意味着重载函数(operator <something>)必须是用户定义类型的成员,或者是具有至少一个用户定义类型参数的独立函数。这正是问题中引用的意思。

然而,独立(非成员)operator newoperator delete函数不需要将用户定义类型的值作为其参数之一。这可能被视为与你的报价相矛盾的事情。

但是,实际上并没有矛盾。这些运营商不是真的超载。当你提供你自己的独立版本operator new/operator delete时,你实际上是替换库提供的。这是语言规范的官方术语:替换,而不是超载。这就是为什么上述报价不适用于operator newoperator delete

+0

'void * operator new(size_t,my_sandbox&)'肯定是一个超载。尽管如此,类成员'new' /'delete'的搜索路径在外部超载。 – Potatoswatter 2010-05-03 05:22:18

+0

是的,但我的意思是,你*可以*编写自己的“standard”operator new:'void * operator new(size_t)'。这一个似乎会违反报价中的要求。但这是合法的。 – AnT 2010-05-03 06:32:35

+0

对不起,'my_sandbox'是一个红鲱鱼。 'void * operator new(size_t,int)'也是一个重载。另外“搜索路径”是不好的措辞。 'operator new'在类范围内查找,使用重载规则,这些规则落在全局范围内,用户可以替换为默认值。我的观点是* *超载和替换都会发生。顺便说一句,你看到我的回答有什么问题吗? – Potatoswatter 2010-05-03 06:46:27

0

operator newoperator delete是基于newdelete表达的操作数的类型,以及任何额外的括号参数new抬头。因此它们可能超负荷(并且受到重载决议影响的operator new),但是通过与其他操作员不同的机制。 (C++ 03§13.5/ 5)

由于它们使用原始内存,它们从不处理指向客户机类类型的指针。 operator new始终采用size_t参数(可能还有其他参数,其中没有一个参数需要用户定义类型)并返回void *operator delete总是需要一个void *参数和可选的size_t,不管它是如何查找的。

我能想到的两个原因:

  • 他们处理原始内存,不包含构造的对象。 operator newoperator delete尝试访问返回的内存块中的对象始终是错误的。 (内存不是用于构建对象,但是,是公平的游戏。)
  • 类成员operator newoperator delete可以是乘法和/或虚拟地继承,使得所讨论的void*不能进行以指向还未构建或已被破坏的子对象,通过任何巫毒。
+0

解释downvote? – Potatoswatter 2010-05-03 06:10:55

+0

尽管讨论了相关的相关领域,但它如何回答实际问题还不是很清楚。我永远不会低调,但也不会有任何提高。 – 2010-05-03 07:30:30

+0

我想我并没有切入正题,但我直接说明了如何在没有用户定义的类型参数的情况下重载它们。我认为这是中心问题......也许我错过了那里的一些东西。 – Potatoswatter 2010-05-03 08:08:41

2

a + b只是为a.operator+(b)operator+(a, b)语法糖。

另一方面,new Foo(x, y, z)不只是语法糖operator new(Foo, x, y, z)或类似的东西。这是方式更复杂:

void* address = operator new(sizeof(Foo)); // here is the behavior you can replace 
try { 
    new(address) Foo(x, y, z); 
} catch (...) { 
    operator delete(address); 
} 

正如你所看到的,功能operator new只是分配内存,这是唯一的什么操作new实际上做了一半。在我看来,将它命名为allocate_memory或类似的东西会更有意义。它绝对不是像operator+这样的运营商。