【问题标题】:C++ std::string syntax "new (&y) std::string(x);"C++ std::string 语法“new (&y) std::string(x);”
【发布时间】:2020-01-04 02:02:36
【问题描述】:

如何理解下面的std::string init 语法?

#include <iostream>
#include <string>

int main ()
{
    std::string y;
    std::string x = "x str";
    new (&y) std::string(x);
    std::cout << y << std::endl;

    return 0;
}

输出:

x str

我们可以把语句分成两步吗?

1.

string* temp = new std::string(x);

2.

(&y) = temp

所以原始语句只是步骤 1 + 2 的捷径。

参考:

1。 https://en.cppreference.com/w/cpp/string/basic_string/basic_string

2。 https://en.cppreference.com/w/cpp/string/basic_string

【问题讨论】:

  • 这里没有什么特别的,只是使用了placement new,这在代码中并不常用。

标签: c++ string constructor


【解决方案1】:

这称为“新展示位置”。基本思想是您提供一个地址,然后它调用该类型的构造函数以在该地址创建一个对象。

在典型情况下,您会给它一个“原始”内存地址,而不是现有对象的地址。事实上,我不确定上面的代码是否真的定义了行为(尽管我必须仔细查看标准以确定它是否存在)。

它最常用于诸如分配原始内存的集合类之类的事情,当您执行insertpush_back 之类的事情时,它会在该内存中构造一个对象。标准集合对象通过分配器对象来处理构造,但最终,它(至少通常)最终会作为 Placement new 完成真正的工作。

您传递给new 的参数将传递给正在创建的对象的构造函数。因此,在您的情况下,它会将x 复制到y 的地址处的新字符串中(即,它将用x 的副本替换y)。

【讨论】:

  • new函数的输入和返回值是什么?例如void* operator new(std::size_t, void*)?语法对我来说并不常见。
  • 我很确定上面的例子会导致它无法运行默认构造字符串中的任何数据的析构函数,这通常是 nullptr。不是很好,但可能不是灾难性的。
  • @AlexanderHuszagh UB 仍然是 UB,问题中的代码会调用它。
  • @Fureeish 但它不会调用 UB,是吗?在已经初始化的对象上调用placement new,虽然容易发生资源泄漏,但只要是和以前一样的对象,它就定义好了,对吗? stackoverflow.com/questions/27552466/…
  • @AlexanderHuszagh 你说得对,我很抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-10
  • 1970-01-01
  • 2013-11-19
  • 1970-01-01
  • 1970-01-01
  • 2020-11-04
相关资源
最近更新 更多