我从来没有完全理解运算符重载的参数列表是如何以系统的方式确定的,而且我对我现在遇到的问题感到特别困惑。
当你重载一元运算符时它有一个参数,如果它是一个类成员则为零。重载二元运算符时,它有两个参数,如果它是一个类成员,则为一个参数。至少那是它似乎工作的方式。我遇到了operator new
(不是班级成员)的问题。
在我正在处理的代码库中,就像我过去看过的其他地方一样(例如here),有一个类似#define new new(__FILE__, __LINE__)
的定义和一个带签名的相应函数{ {1}}或类似内存调试的东西。我注意到我的项目中的那个实际上与之前链接的不同。这给我带来了一个问题,因为由于某种原因,它会弄乱一个新的位置。我查看了 The C ++ Programming Language ,如果它解释了这个我就错过了它。
void *new(size_t size, const char *file, unsigned line)
在这方面是否特别,即它是否具有特定语言定义的额外调试签名?它似乎不是因为,正如我上面提到的,我在不同的地方看到了略微不同的签名。如果是这样,那么其他运营商有哪些非明显的签名,它们是什么?这些不同的签名是一些特定于实现的附加功能吗?如果是这样,关于大多数实现的作用是否有任何一般规则?或者,它是否像我在标题中暗示的那样存在问题?您是否可以在签名中添加尽可能多的额外参数,如果您使用new
关键字本身和您希望的新类型之间的参数调用new,您可以做任何事情吗?或者我更困惑,还有一些我不知道的东西?
最重要的是在短期内(虽然我真的很想理解这一点),是什么让我的位置变得混乱new
?宏正在导致类似new
的扩展。问题可能是括号中的两个组,还是其他什么?
答案 0 :(得分:2)
operator new更接近函数,因为您可以根据需要提供尽可能多的重载,编译器将根据函数重载规则选择版本。
因此,当您执行new ((T1)value1, (T2)value2) TYPE
时,会将其路由到:
operator new(size_t, T1, T2);
你的宏的问题在于它假设你正在调用new的普通版本,并且它可以使用预处理器将其转换为调试new的调用。当您需要调用不同版本的新版本时,宏会被破坏。
如果您需要拨打新的展示位置(或任何其他特殊新内容),您可以通过关闭该宏来修复您的问题:
#undef new
答案 1 :(得分:0)
重载运算符的arity是你声明的任何东西。对于以符号(+)命名的运算符,如果将它们定义为具有额外的args,则只能通过显式调用来调用它们。 (算子+(a,b,c,d,e))。对于operator new,您必须至少给它一个arg,但是您可以根据需要给它。常规运算符重载决定了哪一个被调用。