我遇到了一个小标准头文件<new>
。我以前可能没有看到它的直接使用。对于那些感兴趣的人,这里是the g++ version。
以下是我感兴趣的部分:
struct nothrow_t { };
extern const nothrow_t nothrow;
/** If you write your own error handler to be called by @c new, it must
* be of this type. */
typedef void (*new_handler)();
/// Takes a replacement handler as the argument, returns the previous handler.
new_handler set_new_handler(new_handler) throw();
struct nothrow_t
及其对象nothrow
?是个
对象真的需要extern
?new_handler
何时使用?operator new/delete
都在extern C++
块中声明?答案 0 :(得分:4)
nothrow_t
用于告诉operator new
在向后兼容的“失败时返回null而不是抛出异常”模式下运行。
也就是说,如果你看到这样的代码:
int * idx = new(std::nothrow) int;
在工作中nothrow_t
。对于标准中的相关部分,从(从C ++ 11 N3376开始)17.6.4.6 [replacement.functions] / 1开始,并从那里开始。
回答您的具体问题:
是的,它确实必须是外部的,至少根据18.6 [support.dynamic] / 1,其中包括:
namespace std {
class bad_alloc;
class bad_array_new_length;
struct nothrow_t {};
extern const nothrow_t nothrow;
typedef void (*new_handler)();
new_handler get_new_handler() noexcept;
new_handler set_new_handler(new_handler new_p) noexcept;
}
此外,17.6.2.3 [using.linkage] / 1表示“C ++标准库中的实体具有外部链接(3.5)”。函数和类(例如上面的get_new_handler
和set_new_handler
)没有明确需要注释以具有外部链接,因为它们默认具有外部链接。
new_handler
覆盖正在使用的默认operator new
时,会使用 set_new_handler
。它只是一个函数指针类型。
operator new
的签名未在C中保留。extern "C++"
告诉编译器允许对这些函数执行名称修改和其他C ++特定事务。通过这种方式,您可以将一个转换单元编译为C,将一个转换为C ++,并将它们链接在同一个二进制文件中,而不必担心C land中的某个人定义了与编译器的operator new
冲突的函数。答案 1 :(得分:2)
嗯,这真是一个“请阅读文档,请”的问题。任何关于C ++的好的入门书都应该讨论nothrow
。例如,正如我记得的那样,Bjarne的“The C ++ Programming Language”确实如此。
但无论如何,您使用nothrow
将std::bad_alloc
个异常转换为nullpointer结果,并使用新处理程序来重试失败的分配。
实际上,当您使用::
功能时,请务必将new
放在nothrow
前面,一般情况下使用全局展示位置时,请避免挑选从课程中添加新内容。除了通常应该避免放置new(因为它是非常低级的语言特性),即使它在技术上没有意义,我也会这样做。这是一个好习惯。
示例:
#include <iostream> // std::wcout, std::endl
#include <stdlib.h> // EXIT_FAILURE, EXIT_SUCCESS
#include <new> // std::nothrow
using namespace std;
int main()
{
int* const p = ::new( std::nothrow ) int[0x7fffffff/sizeof(int)];
if( !p )
{
cout << "Allocation failed!" << endl;
return EXIT_FAILURE;
}
cout << "Alles success!" << endl;
delete[] p;
return EXIT_SUCCESS;
}
我的系统输出:
[D:\dev\test] > a Allocation failed! [D:\dev\test] > _
请注意,上面假设是32位进程:)