我重载了全局运算符new / delete / new [] / delete []但是简单的测试表明,虽然我的new和delete版本被正确调用,但使用new []和delete执行简单的数组分配和删除[]导致调用newaop.cpp和delete2.cpp中的实现。
例如,此代码
int* a = new int[10];
在newaop.cpp中调用operator new [],后者又调用我的operator new版本。所以看起来它们全局超载,但由于某种原因不是数组版本。有什么我想念的吗?
编辑:我的运算符实现是在一个单独的项目中,它被编译成一个库并静态链接。回想起来,这可能有助于包含在原始帖子中,因为它可能与此有关。虽然我仍然无法弄清楚为什么只有阵列版本受到影响。答案 0 :(得分:3)
我不知道你是如何重载operator new[]
的,但我只是尝试了MSVC2008:
void* operator new[](size_t size)
{
return 0;
}
int main()
{
int* a = new int[5];
}
上面的代码有效地调用了operator new[]
的错误实现。
所以这是我的猜测:由于某种原因你没有超载operator new[]
,你的程序使用编译器的operator new[]
版本依赖于operator new
来分配内存。由于您重载operator new
,您的实现将被调用。
答案 1 :(得分:0)
operator new分配一个对象并调用其构造函数。 new []分配n个对象并调用n个构造函数。
编辑:有多个new []和delete []重载可能被认为是有点奇怪的。编译器如何知道链接哪一个?你有可能发布你的超载吗?如果你没有链接newaop和delete2(也就是你的exe是exe中唯一的实现),那你也会被调用吗?
答案 2 :(得分:0)
您告诉我们您的代码有问题,但没有发布任何内容:vP。我的猜测是你使用int
作为重载的参数而不是size_t
。可能会调用某些重载,因为编译器决定在该实例中容忍。
答案 3 :(得分:0)
好的,我设法解决了这个问题,所以如果有其他人偶然发现这个问题,我会发布这个帖子。
运算符未被调用的原因是因为我的实现位于库中,而不是在调用运算符的项目中。事实上,从技术上讲,你只需要包含运算符的实现,它们已经全局定义,我只在我的库中指定.cpp中的运算符的实现(这是错误的步骤)。代码显然只包含库中的头文件,并没有实现的可见性。此外,Visual Studio似乎已将newaop.cpp和delete2.cpp链接到我的应用程序中。这两个文件包含operator new []和operator delete []的实现(bot不适用于常规new / delete!)。这很可能是编译器看到这两个实现并在我的库中选择它们的原因,它位于库中的.cpp文件中。
解决方法是将重载运算符的实现移动到库中的头文件中,该文件直接包含在我的代码中。