我真的很困惑在c++中重载全局
operator new
,在这种情况下,我可以将其理解为overload
:
#include <iostream>
using namespace std;
void *operator new( size_t n, const string &pat ) {
char *p = static_cast<char *>(::operator new( n ));
const char *pattern = pat.c_str();
if( !pattern || !pattern[0] )
pattern = "\0"; // note: two null chars
const char *f = pattern;
for( int i = 0; i < n; ++i ) {
if( !*f )
f = pattern;
p[i] = *f++;
}
cout<<"overload!"<<endl;
return p;
}
int main() {
string fill( "<garbage>" );
string *string1 = new string( "Hello" ); // standard version
string *string2 =
new (fill) string( "World!" ); // overloaded version,why??? because fill will be the second parameter
//and the parameter list is different from standard versions in new.h
cout<<string1<<" "<<string2<<endl;
return 0;
}
在这个代码块中,我写了一个重载版本的
operator new
,它使用标准版本::operator new()
,然后我找到了标准版本的位置:
//from new.h
void* operator new(std::size_t) _GLIBCXX_THROW (std::bad_alloc)
__attribute__((__externally_visible__));
标准版中唯一的参数类型是
size_t
,那么我“重载”这个标准版:
#include <iostream>
using namespace std;
//overload1
void *operator new( size_t n, const string &pat ) {
char *p = static_cast<char *>(::operator new( n ));
const char *pattern = pat.c_str();
if( !pattern || !pattern[0] )
pattern = "\0"; // note: two null chars
const char *f = pattern;
for( int i = 0; i < n; ++i ) {
if( !*f )
f = pattern;
p[i] = *f++;
}
cout<<"overload1"<<endl;
return p;
}
//overload2
void* operator new(size_t n){//note:the same parameter as the standard version,why???
cout<<"overload2"<<endl;
return malloc(n);
}
int main() {
string fill( "<garbage>" );
string *string1 = new string( "Hello" ); // overloaded version:2
string *string2 =
new (fill) string( "World!" ); // overloaded version:2 and 1
cout<<string1<<" "<<string2<<endl;
return 0;
}
这次我的
overload1
版本调用的是overload2
版本而不是标准版本,但是这两个版本(overload2
和standard version
)的参数列表是完全一样的!这与我学到的关于重载的东西,我可以理解为替换,因为在new.h
中,有这样一个注释:
这些是可替换的签名: - 普通的单个新建和删除(没有参数,出错时抛出 bad_alloc) - 普通数组新建和删除(相同) - nothrow 单个新建和删除(采用 nothrow 参数,出错时返回 NULL) - nothrow 数组new 和 delete(相同)Placement new 和 delete 签名(采用内存地址参数,什么都不做)可能不会被用户程序替换。
那么,标准版是不是被我的
overload2
版本取代了?还是只是超载了(真的很迷惑),我是不是应该停止声称这种行为是“超载”?但似乎每个人都把它称为“超载” operator new
"