【问题标题】:Initialize std::unique_ptr as a raw array pointer is initialized初始化 std::unique_ptr 作为原始数组指针被初始化
【发布时间】:2019-11-07 17:15:41
【问题描述】:

我目前有一个小型 OpenGL 项目,其中我在堆上创建了一个数组,

float* vertices = new float[48] {
     0.5f,  0.5f, 0.5f,  1.0f, 0.0f, 0.0f,  // front top right,    0
     0.5f, -0.5f, 0.5f,  0.0f, 1.0f, 0.0f,  // front bottom right, 1
    -0.5f, -0.5f, 0.5f,  0.0f, 0.0f, 1.0f,  // front bottom left,  2
    -0.5f,  0.5f, 0.5f,  0.4f, 0.8f, 0.2f,  // front top left,     3

     0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f,  // back top right,     4
     0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,  // back bottom right,  5
    -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,  // back bottom left,   6
    -0.5f,  0.5f, -0.5f, 0.4f, 0.8f, 0.2f   // back top left,      7 
};

我预计将其扩展到数百或一千个值。因此,我想使用std::unique_ptr。我查看了文档,似乎无法像原始数组指针一样初始化std::unique_ptr。尽管如此,我已经尝试过写这样的东西,

std::unique_ptr<float[]> vertices(new float[48])  {
    0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f,     // front top right,    0
    0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f,    // front bottom right, 1
   -0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f,    // front bottom left,  2
   -0.5f, 0.5f, 0.5f, 0.4f, 0.8f, 0.2f,     // front top left,     3

    0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f,    // back top right,     4
    0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,   // back bottom right,  5
   -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,   // back bottom left,   6
   -0.5f, 0.5f, -0.5f, 0.4f, 0.8f, 0.2f     // back top left,      7 
};

无法编译。

是否可以像使用原始指针数组一样初始化 unique_ptr 数组?

我曾考虑过使用std::vector,然后使用unique_ptr“捕获”它,尽管我还没有尝试过。

【问题讨论】:

  • std::vector&lt;float&gt; vertices = { ... } 就完成了。
  • 在第一个代码sn-p中,vertices的类型是“指向浮点的指针”。第二,它应该是“unique_ptr to float”。正如所写,它是“指向浮动指针的唯一指针”。
  • 如果您因为需要指针而避免使用向量,请注意vertices.data()&amp;vertices[0] 将为您提供指向“数组”的指针。
  • 初始化器属于浮点数组,所以移动括号。之后应该工作。不过,向量可能更合适。

标签: c++ arrays initialization std unique-ptr


【解决方案1】:

除非非常特殊的原因,否则您应该使用std::vector。这是动态分配数组的标准类型。 my_vector.data()返回一个指向数据的指针,因此它与OpenGL等C apis兼容。

// on the heap
std::vector<float> vertices = {
     0.5f,  0.5f, 0.5f,  1.0f, 0.0f, 0.0f,  // front top right,    0
     0.5f, -0.5f, 0.5f,  0.0f, 1.0f, 0.0f,  // front bottom right, 1
    -0.5f, -0.5f, 0.5f,  0.0f, 0.0f, 1.0f,  // front bottom left,  2
    -0.5f,  0.5f, 0.5f,  0.4f, 0.8f, 0.2f,  // front top left,     3

     0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f,  // back top right,     4
     0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,  // back bottom right,  5
    -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,  // back bottom left,   6
    -0.5f,  0.5f, -0.5f, 0.4f, 0.8f, 0.2f   // back top left,      7 
};

如果您想要矢量(如果您需要调整大小等),只需使用std::vector&lt;float&gt; 作为类型而不是std::array&lt;float, 48&gt;


现在如果你想修正你的语法但仍然使用动态内存和指针(我建议不要这样做,因为它用于 OpenGL 顶点并且你事先知道大小)只需替换类型,用新数组构造它里面:

std::unique_ptr<float[]> vertices(new float[48] {
     0.5f,  0.5f, 0.5f,  1.0f, 0.0f, 0.0f,  // front top right,    0
     0.5f, -0.5f, 0.5f,  0.0f, 1.0f, 0.0f,  // front bottom right, 1
    -0.5f, -0.5f, 0.5f,  0.0f, 0.0f, 1.0f,  // front bottom left,  2
    -0.5f,  0.5f, 0.5f,  0.4f, 0.8f, 0.2f,  // front top left,     3

     0.5f,  0.5f, -0.5f, 1.0f, 0.0f, 0.0f,  // back top right,     4
     0.5f, -0.5f, -0.5f, 0.0f, 1.0f, 0.0f,  // back bottom right,  5
    -0.5f, -0.5f, -0.5f, 0.0f, 0.0f, 1.0f,  // back bottom left,   6
    -0.5f,  0.5f, -0.5f, 0.4f, 0.8f, 0.2f   // back top left,      7 
});

std::unique_ptr 类型有一个构造函数,它接受一个指向 T 类型的指针。构造函数只是显式的,所以只能使用直接初始化。

这是一个live example,包含所有构造函数类型。

【讨论】:

  • 您能解释一下为什么使用std::array 而不是原生数组吗?
  • @Deduplicator 为什么是原生数组?
  • 我希望能够在堆上分配更大的数组结构。可以直接用std::vectorstd::array 完成吗?如果没有,我是否仍然可以选择使用std::vectorstd::array,然后选择使用std::unique_ptr&lt;std::vector&gt; 来利用堆内存?
  • @GuillaumeRacicot 因为你不需要提供一个(DRY)的大小,而且它只使用核心语言?
  • @user34299 向量直接在堆上分配所有数据。它将大小和容量以及数据指针保存在堆栈中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-17
  • 2018-11-30
  • 1970-01-01
相关资源
最近更新 更多