【问题标题】:Can a smart pointer be forward declared and initialized separately?可以单独前向声明和初始化智能指针吗?
【发布时间】:2020-04-19 03:24:49
【问题描述】:

我正在尝试学习如何在 Cpp 中使用智能指针,但遇到了障碍;我想在我的代码的一部分中将我的变量声明为 unique_ptr,可能作为类成员或命名空间的一部分,然后在我的代码的其他地方初始化/“make_unique”。我已经阅读了很多关于智能指针和不完整类型信息的问题,但我不确定我是否完全理解。这是我读到的最后一个资源; Incomplete types and shared_ptr / unique_ptr

这是我正在尝试使用的玩具代码。 'v1' 按预期工作,在一行上。 'v2' 是我想要做的工作

std::unique_ptr<glm::vec3>v1 = std::make_unique<glm::vec3>(); //Works as expected
std::unique_ptr<glm::vec3>v2; //Declare a unique_ptr here, but i don't want to allocate any memory for it yet...

//do things i need to do before memory is allocated to v2

v2 = std::make_unique<glm::vec3>(); //...NOW I want to allocate memory for v2 and prepare it to be used

这些是我从 VS2017 得到的错误,都指的是我 make_unique v2 所在的行:

错误 C4430:缺少类型说明符 - 假定为 int。注意:C++ 不支持 default-int

错误 C2371:'templategl::v2':重新定义;不同的基本类型

编辑:是的,我应该提供一个更好的例子。在创建一个时,我回答了我自己的问题。修改后的代码如下;

#include <memory>
#include <iostream>

struct vec3 {
    vec3() { x = y = z = 1.f; }
    vec3(float val) { x = y = z = val; }
    float x, y, z;
};

//smart pointers in a namespace...
namespace smptrns {
    std::unique_ptr<vec3>v0; //will be init in a namespace function
    std::unique_ptr<vec3>v1 = std::make_unique<vec3>(); //Works as expected
    std::unique_ptr<vec3>v2; //Declare a unique_ptr here, but i don't want to allocate any memory for it yet...
    //v2 = std::make_unique<vec3>(); //...NOW I want to allocate memory for v2 and prepare it to be used
    //^This is my problem, initializing v2 in namespace outside of a function.
    void initpntr() {
        v0 = std::make_unique<vec3>(); //Works
    }
}

int main() {
    smptrns::initpntr();
    smptrns::v2 = std::make_unique<vec3>(5.f); //Also works
    std::cout << smptrns::v0->x << "\t" << smptrns::v1->x << "\t" << smptrns::v2->x << "\n";
}

我试图在函数之外初始化 v2 ,通过从命名空间中的函数或在我的主循环中分配给它并使用 :: 运算符直接访问它来修复。

【问题讨论】:

  • 无法复制:demo。请提供一个可验证的完整示例
  • 声明v2 = std::make_unique&lt;glm::vec3&gt;();的上下文是什么?它在函数内吗?如果没有,请参阅,例如"Code outside functions".
  • 您可能已经在某个地方草草得出结论,现在正在错误的道路上寻求帮助。忘记您认为导致编译器错误的原因;而是询问您的编译器错误,并以minimal reproducible example 为备份。
  • 您的第一个错误表明您在函数之外编写了此分配。第二个错误来自您在函数之外编写它,使其成为int 的声明。买一本好书,从头开始。

标签: c++ pointers unique-ptr


【解决方案1】:

您可以声明一个全局或命名空间范围对象,而无需使用 extern 关键字对其进行初始化:

extern std::unique_ptr<glm::vec3> v2; // Declaration only.
// ...
std::unique_ptr<glm::vec3> v2 = std::make_unique<glm::vec3>(); // Declaration and definition with initialization.

【讨论】:

    猜你喜欢
    • 2011-06-14
    • 1970-01-01
    • 2017-11-20
    • 2014-09-08
    • 2017-01-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    相关资源
    最近更新 更多