unique_ptr 的正确用法是什么?

问题描述 投票:0回答:2

我目前正在努力理解

unique_ptr
的目的。

我希望在其他地方对存储在

std::unique_ptr<Component> component
类的任何实例中的
Object
内容进行某种引用。由于我们使用智能指针,原始指针
pComp
永远不应该管理内存本身,因为
unique_ptr
是唯一负责它的,这是智能指针的核心原则之一。然而,令我困惑的是,一旦我们超出范围并调用
unique_ptr
的析构函数(这反过来会释放内存),我就无法检查内存在代码的其他部分是否仍然有效引用但不拥有相同的内存地址(在本例中为
pComp
)。
我知道使用
unique_ptr
是一个非常明确的声明,说明
Object
是该内存的所有者,其他人不应对它负责,但是如果我的其余代码无法检查内存是否仍然有效?
为什么
unique_ptr
不将其内部指针设置为
nullptr
?我是否误解了
unique_ptr
的用法?有正确的方法吗?如果在这种情况下我应该使用
shared_ptr
,为什么要这样呢,因为我希望 Object 是唯一负责的呢?预先感谢大家。

#include <iostream>
#include <memory>

class Component
{
public:
    Component() { std::cout << "Component Constructor" << std::endl; }
    ~Component() { std::cout << "Component Destructor" << std::endl; }
};

class Object
{
public:
    std::unique_ptr<Component> component;

    Object() : component(std::make_unique<Component>()) { std::cout << "Object Constructor" << std::endl; }
    ~Object() { std::cout << "Object Destructor" << std::endl; }
};

int main()
{
    Component* pComp = nullptr;
    {
        Object obj;
        pComp = obj.component.get();
    }

    if (pComp == nullptr)
        std::cout << "pComp is nullptr\n"; // This code is never reached.

    return 0;
}
c++ memory-management smart-pointers unique-ptr
2个回答
1
投票

在您的示例中,

pComp
具有由obj.component存储的指针值的
副本
。当
obj
被破坏时,该指针值的副本将变得无效。 C++ 中没有办法测试无效指针,程序员需要确保它们永远不会被访问。

为什么 unique_ptr 不将其内部指针设置为 nullptr?

unique_ptr
不会在其析构函数中将其底层指针清空,因为该指针即将不复存在。

有正确的方法吗?

不,您应该延长

obj
的生命周期,或者用您自己的
obj.component
获得
unique_ptr
的所有权。只有当您无法做到其中任何一个时,您才应该考虑更改为
shared_ptr


1
投票

所以使用

unique_ptr
而不是指针。然后你会得到:

int main()
{
    std::unique_ptr<Component> pComp;
    {
        Object obj;
        pComp = obj.component; // compile error
    }
}

如果您想要

std::move
组件脱离对象,或者您必须使用对象组件,这取决于您。

那么如果我的其余代码无法检查内存是否仍然有效,那么使用它还有什么意义呢?

RAII 风格自动内存释放。

为什么 unique_ptr 不将其内部指针设置为 nullptr?

为什么会这样?这是一个必须执行的指令,那就是时间。

有正确的方法吗?

这取决于 you you 定义对象的“正确”语义。 C++就是锤子,看你敲到哪里。

我应该在哪里使用shared_ptr,为什么要这样,因为我希望Object是唯一负责的?

听起来好像不行,我想你也想将 unique_ptr 设置为常量,这样你就无法移出它。

class Object
{
public:
    const std::unique_ptr<Component> component;

...
    {
        Object obj;
        pComp = std::move(obj.component); // also compile error
    }

唯一的方法是使用

obj.component
来访问组件。但是,您仍然可以使用
.get()
并获取原始指针。由程序员编写正确的代码。

© www.soinside.com 2019 - 2024. All rights reserved.