如何在智能指针中获取目标对象的地址?

How could I get address of the target object in smart pointer?

我正在尝试通过间接指针实现链表,它在 TED Talk.

上介绍过

我指的是felipec's implementation on github and made an version by raw pointer, this is the github link.

这是完整代码的一部分,_find是一个函数,可以找到目标节点的间接指针,即*indirect == target node :

//...
struct Node {
    int data;
    Node *next;
    Node()
        : data(0), next(nullptr) {}
    Node(int _d, Node *_next = nullptr)
        : data(_d), next(_next) {}
    ~Node() { puts("~Node"); }
};
//...

List::Node **List::_find(const int target)
{
    Node **indirect = &head;
    while (*indirect && (*indirect)->data != target)
        indirect = &(*indirect)->next;

    return indirect;
}

我想制作一个智能指针版本。我在 Node 中使用 std::unique_ptr 作为 next 指针,在 List.

中使用 std::shared_ptr 作为 head 指针

但是在Node **indirect = &head部分,我不知道如何通过智能指针来设计它,我是这样写的:

//...
struct Node {
    int data;
    std::unique_ptr<Node> next;
    Node()
        : data(0), next(nullptr) {}
    Node(int _d, std::unique_ptr<Node> &_next)
        : data(_d), next(std::move(_next)) {}
    ~Node() { puts("~Node"); }
};
//...

List::Node **List::_find(const int target)
{
    Node **indirect = &(head.get());
    while (*indirect && (*indirect)->data != target)
        indirect = &(*indirect)->next;

    return indirect;
}

显然,Node **indirect = &(head.get()) 不是一个好主意,因为 get 函数 return 它指向一个右值。但是我需要的是指向target的指针对象,代码连编译都编译不了

因此,有两个问题

  1. 如何获取智能指针中目标对象的地址?

  2. 我是否正确使用了智能指针?我应该将 shared_ptr 更改为 unique_ptr,还是不使用智能指针?

感谢任何额外的补充和建议。

How could I get the address of the target object in smart pointer?

我认为你的意思是“智能指针中指针的地址”,因为目标对象的地址就是你用.get()得到的。 std::unique_ptr 不提供任何接口来直接访问它的指针成员,所以这是不可能的。

Did I use the smart pointer in correct way? Should I change shared_ptr to unique_ptr, or just not use smart pointer for it?

使用std::unique_ptr 是正确的做法。您不需要 shared_ptr 因为任何给定节点永远不会有两个所有者。

在您的第一个代码中,indirect 是指向 Node/List 结构中的原始指针的指针。由于您将这些更改为智能指针,因此 indirect 也应该成为指向智能指针的指针:

std::unique_ptr<List::Node> *List::_find(const int target)
{
    std::unique_ptr<Node> *indirect = &head;
    while (*indirect && (*indirect)->data != target)
        indirect = &(*indirect)->next;

    return indirect;
}

虽然用 return 引用会更惯用:

std::unique_ptr<List::Node> &List::_find(const int target)
{
    std::unique_ptr<Node> *indirect = &head;
    while (*indirect && (*indirect)->data != target)
        indirect = &(*indirect)->next;

    return *indirect;
}

(我假设这是一个私有辅助函数,实际上不是 List class 的接口,在这种情况下,任何一个实现都会有问题。)