c++ - 如何初始化由 unique_ptr 管理的数组的元素?

标签 c++ c++11 std unique-ptr

我们知道资源获取是初始化 (RAII),我寻找语法来初始化具有参数(没有默认参数)的对象数组,由 unique_ptr 管理,但我没有找到随便举个例子,Cppreference里面有构造int

int size = 10; 
std::unique_ptr<int[]> fact(new int[size]);

我怎么能这样写:

class Widget
{
 Widget(int x, in y):x_(x),y_(y)
 {}
 int x_,y_;
};

 std::unique_ptr<Widget[]> fact(new Widget[size]);

最佳答案

按照推荐链接中的最后一个答案
How can I make new[] default-initialize the array of primitive types? ,
我想出了下面这个小例子:

#include <iostream>
#include <memory>
#include <string>

class Widget {
  private:
    std::string _name;
  public:
    Widget(const char *name): _name(name) { }
    Widget(const Widget&) = delete;
    const std::string& name() const { return _name; }
};

int main()
{
  const int n = 3;
  std::unique_ptr<Widget[]> ptrLabels(
    new Widget[n]{
      Widget("label 1"),
      Widget("label 2"),
      Widget("label 3")
    });
  for (int i = 0; i < n; ++i) {
    std::cout << ptrLabels[i].name() << '\n';
  }
  return 0;
}

输出:

label 1
label 2
label 3

Live Demo on coliru

诀窍是使用初始化列表。

我有点不确定这是否涉及复制构造(这在小部件类库中通常是被禁止的)。可以肯定的是,我写了 Widget(const Widget&) = delete;

我不得不承认这适用于 C++17,但之前不行。


我对第一个例子做了一些改动。

我也试过

new Widget[n]{
  { "label 1" },
  { "label 2" },
  { "label 3" }
});

成功,直到我意识到我忘记在第一个示例中使构造函数显式。 (通常,小部件集不允许这样做——以防止意外转换。)修复此问题后,它不再编译。

介绍一下,它甚至可以使用 C++11 编译的移动构造函数:

#include <iostream>
#include <memory>
#include <string>

class Widget {
  private:
    std::string _name;
  public:
    explicit Widget(const char *name): _name(name) { }
    Widget(const Widget&) = delete;
    Widget(const Widget &&widget): _name(std::move(widget._name)) { }
    const std::string& name() const { return _name; }
};

int main()
{
  const int n = 3;
  std::unique_ptr<Widget[]> ptrLabels(
    new Widget[n]{
      Widget("label 1"),
      Widget("label 2"),
      Widget("label 3")
    });
  for (int i = 0; i < n; ++i) {
    std::cout << ptrLabels[i].name() << '\n';
  }
  return 0;
}

输出:如上

Live Demo on coliru

关于c++ - 如何初始化由 unique_ptr 管理的数组的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52216835/

相关文章:

c++ - 为什么 Clang 会自动向我的函数添加属性?

c++11 - 如何检测 snprintf 故障?

c++ - std::vector<Class *> 没有正确构造拷贝

c++ - 内存中的 FAT 文件系统

c++ - std::function 是否允许在其返回类型中从引用到拷贝进行隐式转换?

c++ - 如何在 std::map 中使用表示不透明字节的类?

c++ - typedef 函数不是类型名?

c++ - 我是否保证在 move vector 后指向 std::vector 元素的指针有效?

c++ - 在异步调用中将 shared_ptr 作为参数传递

c++ - std::experimental::filesystem::recursive_directory_iterator 跳过文件夹及其子文件夹