重载运算符new和异常正确性

时间:2013-10-31 12:43:44

标签: c++ exception

在查看遗留代码时,我发现了类似于以下代码的内容

void* legacy_type::operator new(size_t size) {
    return pool_alloc(size);
}

已知pool_alloc在发生故障时永不抛出并返回0。

这里的std :: nothrow变体没有重载。

我想知道这段代码是否在语义上是正确的,并且具有良好定义的行为。

new (std::nothrow) legacy_type;应该使用自定义pool_alloc吗?在我的编译器中它根本不编译。这是明确定义的行为吗?

如果重载this==0返回零,构造函数是否会因operator new而运行并崩溃?在我的编译器中它运行(并在成员初始化时崩溃)。这是标准定义良好的行为吗?

1 个答案:

答案 0 :(得分:1)

1)不,不应该。这些是不同的功能。并且,当你重载其中一个操作时 - 所有其他操作将永远不会工作,如果它们没有重载,因为如果类范围中有operator new并且签名是不可接受的,那么编译器将不会搜索全局{ {1}},因此,将发生编译错误。

2)如果operator new将返回空指针,则会中断后置条件。 n3376 18.6.1.1/3

必需的行为:将非空指针返回到适当对齐的存储(3.7.4),否则抛出bad_- 分配例外。 此要求对此函数的替换版本具有约束力。

如果要返回0,则应使用以下签名

new

如果你使用这个重载并从中返回0,则没有seg-fault。

n3376 5.3.4 / 13

如果 分配函数返回null,不进行初始化,不调用deallocation函数, 并且new-expression的值应为null。