谁定义新操作员
Who defines the new operator?
这个程序应该编译吗?
int main(){
double* p = new double[4];
delete[] p;
return 0;
}
(它确实与GCC 7.1.1一起编译(
我之所以这么问,是因为我不确定是谁在提供operator new
的定义。是语言吗?编译器默认是#include
还是<new>
?
为了使这个问题更加清楚,我实际上可以定义(覆盖?(运算符new
。
#include<cstdlib> // malloc and size_t
#include<cassert> // assert
void* operator new[](unsigned long int sz){ // what if this is not defined? who provides `new`?
assert(0); // just to check I am calling this function
return std::malloc(sz);
}
int main(){
double* p = new double[4]; // calls the new function above
delete[] p;
return 0;
}
我在这里干什么?
是否覆盖new
?new
过载?new
的定义对编译器来说是特别的(神奇的(吗?(例如,如果未定义,则使用提供的语言(。#include<new>
在这一切中的作用是什么?
这里有一个new
表达式,它实际上调用operator new[]
void* operator new[]( std::size_t count );
编译器在每个翻译单元中隐式声明基本的operator new
s(这是由标准指定的(,请参阅cpprreference文档。
版本(1-4(在每个翻译单元中被隐式声明,即使<不包括new>标头
在您的第二个代码片段中,您正在重载(从技术上讲,您实际上是在替换(operator new
(而不是覆盖,这仅用于虚拟函数(,尽管您应该重载operator new[]
(注意,如果您不重载,那么operator new[]
将回到operator new
,所以从技术上讲,我相信您的代码是可以的,但为了清晰起见,我只是重载数组版本(。
运算符new可能存在其他重载。标量和数组版本都是由编译器提供的,可能是由标准库提供的,也可能是由用户代码提供的。
如果你自己写(如果它们没有内置版本的签名(或者如果你#包含new,则会有额外的new(和delete(重载。如果您提供了与内置签名匹配的运算符,那么它们将替换内置版本。小心。:(
人们包括的主要原因是
1( 在用户提供的存储器地址中构造对象
2( 新的非投掷版本
当然,也存在运算符删除重载,因为新的/delete必须成对重载才能协同工作,否则几乎肯定会发生破坏。如果您的操作员new与内置签名匹配,它将替换而不是重载内置版本。
记住,一个简单的"新表达":
std::string myString = new std::string();
真正的工作分为两部分:1(分配内存(通过操作符new(,然后,2(在内存中构造一个对象。如果成功,它将返回指向该对象的指针;如果失败,它将清理构建的内容,释放分配的内容,然后抛出。
当您重载运算符new时,您只处理内存分配,而不是构造函数调用,并且对象将在该运算符返回的任何地址中构造。对于新的正常放置,你可能会看到这样的代码:
char myBuffer[1024]; // assume aligned; nobody needs more than 1024 bytes
std::string *ptr = new (myBuffer) std::string();
assert (ptr == &myBuffer);
new的额外参数是myBuffer地址,它由操作符new立即返回,并成为构建对象的地方。断言应该通过,并显示字符串是在myBuffer的字节中创建的。
new的无抛出版本在#included new之后也可用,它还使用了一个额外的运算符参数:
char * buf = new (std::nothrow) char[MAX_INT];
if (buf) {
std::cout << "WHOA, you have a lot of memory!!!n";
}
现在,它不会失败,而是返回一个空指针,所以你必须检查它
- 谁定义新操作员
- 使用自定义参数的过载删除操作员
- 警告定义朋友操作员在名称空间内声明
- 在模板类成员函数中无法使用以前定义的过载操作员
- 如何定义指针铸件操作员
- 如何在C 中定义一个副操作员
- 无法找到在全局名称空间中定义的操作员
- 使用用户定义的转换操作员隐式转换
- 是否可以使用明确的模板参数调用模板的用户定义转换操作员
- 在定义C2679和C2678错误代码的地方未找到二进制操作员
- 写一个最小的自定义操作员:std :: Sort需要std :: __ lg为我的类型解释
- 将别名定义为操作员
- C 如何将对象数据传递到用户定义的转换操作员中
- 仅覆盖自定义数据架构的迭代器的操作员*()
- 在自定义双链接列表中的自定义迭代器的取消运算符,找不到二进制操作员
- 复制分配操作员定义
- C ,重新定义操作员=,为矩阵分配一个子序列
- 在模板类中专门定义错误的朋友操作员
- 对未定义的C++班次操作员行为和换行"pattern space"感到困惑
- Stable_sort缺少操作员 - 定义了自定义比较函数