【问题标题】:Initializing a variable to an object from a vector holding derived classes从包含派生类的向量初始化变量为对象
【发布时间】:2016-07-15 04:48:09
【问题描述】:

我有一个向量,它包含从基类“SceneObject”派生的类的对象。对于这个任务,我发现我必须使用唯一指针,如下所示:

vector<std::unique_ptr<SceneObject>> objects;

为了将我的对象放入这个向量中,我使用 new 关键字在堆上分配内存:

objects.emplace_back(new Sphere(glm::vec3(0.9, -1.925, -6.69), 0.825, sphereMaterial));

我在循环中从这些对象访问函数,例如:

objects[k]->intersect(...);

但我的问题是我想初始化一个变量“SceneObject”,该变量将包含存储在此向量中的对象之一,以便稍后执行一些检查......我正在尝试存储指针,因为我认为我应该这样做,但是这样做时出现编译器错误:

SceneObject* object = NULL;
for(...)
    object = &objects[k];

错误:

boilerplate.cpp: In function 'int main(int, char**)':
boilerplate.cpp:606:15: error: cannot convert '__gnu_cxx::__alloc_traits<std::allocator<std::unique_ptr<SceneObject> > >::value_type* {aka std::unique_ptr<SceneObject>*}' to 'SceneObject*' in assignment
    object = &objects[k];
           ^

我使用this example code 中看到的这种方法来创建我的基类/派生类。

关于我应该如何用我的对象初始化这个变量有什么建议吗?

【问题讨论】:

  • 为什么不使用std::shared_ptr

标签: c++ pointers unique-ptr


【解决方案1】:

您需要在 std::unique_ptr 上调用 get to "unwrap" the raw pointer 存储在里面:

SceneObject* object = NULL;
for(...)
    object = objects[k].get();

请注意,在您拥有 API 的情况下,您可以避免解开指针:std::unique_ptr 提供解引用运算符,允许您将它们视为实际指针。

【讨论】:

    【解决方案2】:

    请记住 unique_ptr 的实际含义:它是一个管理指针的对象,并且只允许一个实例指向给定的对象。

    所以你的向量的一个元素是unique_ptr,这意味着当你做objects[k]时,你会得到一个unique_ptr对象。您正在尝试在此处初始化 SceneObject* 指向 unique_ptr* 的指针:

    SceneObject* object = NULL; object = &objects[k];

    但显然SceneObject* != unique_ptr*

    智能指针的目标是避免使用原始指针,所以如果你在向量中使用unique_ptr,并且对被破坏的向量元素很好,你也应该在循环中使用unique_ptr&lt;SceneObject&gt; object; .然后就是:

    for(...) object = objects[k];

    如果您希望它们在向量中保持有效,您应该在两个位置都使用shared_ptr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-03
      • 1970-01-01
      • 2013-05-15
      • 2015-01-02
      • 1970-01-01
      • 2016-12-09
      相关资源
      最近更新 更多