如何初始化由unique_ptr管理的数组的元素? [英] How to initialize elements of an array managed by a unique_ptr?

查看:150
本文介绍了如何初始化由unique_ptr管理的数组的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们知道资源获取是初始化(RAII),我寻找了一种语法来初始化由 unique_ptr 管理的具有参数(没有默认参数)的对象数组,但是我没有找到任何例子中,Cppreference都构造一个int

We know that Resource Acquisition is Initialization (RAII), I looked for the syntax to initialize an array of objects that have parameters (with no default params), managed by unique_ptr but I did not find any example, there is one in Cppreference constructing 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]);

推荐答案

在建议的链接中遵循最后一个答案
如何可以使 new [] 默认初始化原始类型的数组吗?
我想到了以下小例子:

Following the last answer in the recommended link
How can I make new[] default-initialize the array of primitive types?,
I came up with the following small example:

#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

在大肠杆菌上进行实时演示

诀窍是使用初始化列表.

The trick is to use an initializer list.

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

I was a bit unsure whether this involves copy construction (which is often forbidden in widget class libaries). To be sure, I wrote Widget(const Widget&) = delete;.

我必须承认这适用于C ++ 17,但以前不适用.

I have to admit that this works with C++17 but not before.

我在第一个示例中摆弄了一些.

I fiddled a bit with the first example.

我也尝试过

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

取得成功,直到我意识到在第一个示例中忘记使构造函数 explicit 为止.(通常,窗口小部件集不允许此–防止意外转换.)修复此问题后,它不再编译.

with success until I realized that I forgot to make the constructor explicit in first example. (Usually, a widget set wouldn't allow this – to prevent accidental conversion.) After fixing this, it didn't compile anymore.

介绍了一个即使在C ++ 11中也可以编译的move构造函数:

Introducing, a move constructor it compiles even with 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;
}

输出:如上

coliru上的实时演示

这篇关于如何初始化由unique_ptr管理的数组的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆