C++0x 仍然可以使用全局运算符 new 显式分配吗?

发布于 2024-09-25 16:32:31 字数 1054 浏览 1 评论 0原文

维基百科指出:

使用运算符 new 可以使类型无法分配:

struct NonNewable {
    void *operator new(std::size_t) = 删除;
};

这种类型的对象只能作为堆栈对象或其他类型的成员进行分配。如果没有不可移植的技巧,它不能直接进行堆分配。 (由于放置 new 是在用户分配的内存上调用构造函数的唯一方法,并且如上所述已禁止这种使用,因此无法正确构造该对象。)

删除运算符 new 类似于在当前 C++ 中将其设为私有,但不是这样t 显式使用全局运算符 new,这避免了特定于类的查找,仍然有效 C++0x?

NonNewable *p = ::new NonNewable();
// neither non-portable nor trickery, though perhaps not widely known

我是否遗漏了草稿中的某些内容?


需要明确的是,这是有效的 C++03 并且工作正常

struct NonNewable {
private:
  void *operator new(std::size_t);  // not defined
};

int main() {
  // ignore the leaks, it's just an example

  void *mem = operator new(sizeof(NonNewable));
  NonNewable *p = ::new(mem) NonNewable();

  p = ::new NonNewable();

  return 0;
}

Wikipedia states:

A type can be made impossible to allocate with operator new:

struct NonNewable {
    void *operator new(std::size_t) = delete;
};

An object of this type can only ever be allocated as a stack object or as a member of another type. It cannot be directly heap-allocated without non-portable trickery. (Since placement new is the only way to call a constructor on user-allocated memory and this use has been forbidden as above, the object cannot be properly constructed.)

Deleting operator new is similar to making it private in current C++, but isn't explicitly using global operator new, which avoids class-specific lookup, still valid C++0x?

NonNewable *p = ::new NonNewable();
// neither non-portable nor trickery, though perhaps not widely known

Have I missed something in the draft?


To be clear, this is valid C++03 and works fine:

struct NonNewable {
private:
  void *operator new(std::size_t);  // not defined
};

int main() {
  // ignore the leaks, it's just an example

  void *mem = operator new(sizeof(NonNewable));
  NonNewable *p = ::new(mem) NonNewable();

  p = ::new NonNewable();

  return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

墨离汐 2024-10-02 16:32:31

我相信你是对的,维基百科是错的。 C++0x 草案标准将“删除的函数”(8.4p10) 描述为不能以任何方式使用的函数(否则程序格式错误)。与普通函数不同,它们在范围或名称查找中不发挥作用。关于新表述的相关段落保持不变:

[5.3.4p8] new 表达式通过调用分配函数来获取对象的存储空间 (3.7.4.1)。 ...

[5.3.4p9] 如果 new 表达式以一元 :: 运算符开头,则在全局范围中查找分配函数的名称。否则,如果分配的类型是类类型 T 或其数组,则在 T 的范围内查找分配函数的名称。如果此查找未能找到名称,或者分配的类型不是类类型,则分配函数的名称将在 T 的范围内查找。在全局范围内查找函数的名称。

所以是的,表达式 ::new NonNewable [或 ::new(mem) NonNewable] 将选择 ::operator new 的重载,忽略函数 NonNewable::operator new,并且不会使程序格式错误。

I believe you are right and wikipedia is wrong. The C++0x draft standard describes "deleted functions" (8.4p10) as functions which may not be used in any way (or else the program is ill-formed). They play no part in scope or name lookup different from normal functions. And the relevant paragraphs concerning new expressions have remained the same:

[5.3.4p8] A new-expression obtains storage for the object by calling an allocation function (3.7.4.1). ...

[5.3.4p9] If the new-expression begins with a unary :: operator, the allocation function's name is looked up in the global scope. Otherwise, if the allocated type is a class type T or array thereof, the allocation function's name is looked up in the scope of T. If this lookup fails to find the name, or if the allocated type is not a class type, the allocation function's name is looked up in the global scope.

So yes, the expression ::new NonNewable [or ::new(mem) NonNewable] would choose an overload of ::operator new, ignoring the function NonNewable::operator new, and would not make the program ill-formed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文