2

我从来没有完全理解运算符重载的参数列表是如何以系统的方式确定的,而且我对现在的问题特别困惑。运算符重载(特别是'new')参数如何工作?

当你重载一元运算符时,它有一个参数,或者如果它是一个类成员,则为零。当你重载一个二元运算符时,它有两个参数,或者一个是类成员。至少这是它看起来工作的方式。但是,我遇到了operator new(不是班级成员)的问题。

在一个代码库,我的工作中,在其他地方,我在过去已经看到(如here例如)有一个这样定义#define new new(__FILE__, __LINE__),并签名void *new(size_t size, const char *file, unsigned line)或类似的东西了内存调试相应的功能。我注意到,我的项目中的那个与以前链接的不一样。这对我来说存在一个问题,因为出于某种原因,它正在搞乱新的放置。我查看了C++编程语言,如果它解释了这一点,我很想念它。

new是否在这方面是特殊的,即它是否有特定的语言定义额外的调试签名?它看起来不像是因为,正如我上面提到的,我在不同的地方看到了略有不同的签名。如果是这样,其他运营商有什么不明显的签名,它们是什么?这些不同的签名而不是某些实现特定的额外功能?如果是这样,那么对于大多数实现有什么一般规则吗?或者,这是否像我在我的标题中暗示的一样?你可以在签名中加入任意数量的额外参数吗?如果你使用new关键字本身和你想要的新类型之间的参数来调用new,你可以做任何事情?还是我更加困惑,还有什么我失踪?

最重要的是在短期内(虽然我真的很想明白这一点),发生什么事情弄乱了我的位置new?该宏正在导致类似new ("file.cpp", 100) (class_pointer) class_t的扩展。括号内的两个问题可能是问题还是其他问题?

回答

0

重载运算符的参数数量是任何声明。对于以符号(+)命名的运算符,如果将它们定义为具有额外的参数,则只会通过显式调用来调用它们。 (运算符+(a,b,c,d,e))。对于新操作员,您必须至少给出一个参数,但您可以根据需要多给它。常规运算符重载决定调用哪一个。

2

operator new更接近函数,因为您可以根据需要提供尽可能多的重载,编译器将根据函数过载规则选择版本。

所以,当你做new ((T1)value1, (T2)value2) TYPE,将被路由到:

operator new(size_t, T1, T2); 

与宏的问题是,它是假设您呼叫的新的普通版本,它可以使用预处理程序把它变成调试新的调用。当您需要调用不同版本的新版本时,该宏会被破坏。

如果您需要调用放置新的(或任何其他特殊新),就可以解决您的问题通过关闭宏:

#undef new