简体   繁体   中英

How to return a smart pointer?

I have a key, and a pointer to left and right nodes defined in a struct, in a class for a binary search tree.

I was getting parasoft errors within the copy helper function of the class, so was advised to change the code to:

BinaryTree::Node* BinaryTree::copyHelper(const Node* other)
{
    if(other == NULL)
    {
        return NULL; // If there's no Node to copy, return NULL.
    }
    else
    {
        //Node* newNode  = new Node; 

        typedef std::unique_ptr<Node> NodePtr;  
        NodePtr newNode(new Node); 

        if(newNode)
        {
            newNode->name  = other->name;
            newNode->left  = copyHelper(other->left); 
            newNode->right = copyHelper(other->right);
        }

        return newNode;
    }
}

Now I am getting an error on the return statement of the newNode:

IntelliSense: no suitable conversion function from NodePtr to BinaryTree::Node *

Any Ideas?

Ahah. You can't convert a unique_ptr<T> to a T* . They're not the same type, and they don't have the same semantics particularly when they get copied. This is why unique_ptr<T> doesn't have a conversion operator to T* . T* isn't a class, so you can't rely on polymorphism to do the work for you like you can with returning a subclass of the declared return type (and in fact unique_ptr 's semantic differences would mean that subclassing would be the wrong relationship anyway).

So you don't have a choice here - you have to return a unique_ptr<T> and have your callers deal with the consequences as they need to know it's a unique_ptr<T> and behaves like one. If you feel this is too much of a burden, I suggest reading up on smart pointers to understand better what they are and what they do for you.

You might also need to consider if it's the correct kind of smart pointer class, as maybe shared_ptr<T> has more suitable semantics for you.

If I understand it copyHelper is an internal function, not part of the interface. If that is so, then the simplest solution is changing the signature to return a unique_ptr rather than a raw pointer.

The alternative is calling release on the unique_ptr inside copyHelper to give up ownership, and let the caller reclaim it in it's own unique_ptr (for that you will need to use reset ), but there is no point in going through a raw pointer when you are going to store it in a unique_ptr in the very next step.

This is your function:

BinaryTree::Node* BinaryTree::copyHelper(const Node* other) { ...}

It returns a BinaryTree::Node* , and it should be returning a unique_ptr<Node> :

std::unique_ptr<BinaryTree::Node> BinaryTree::copyHelper(const Node* other) { ...}

函数的返回类型和您实际返回的值具有不同的类型,并且在您返回的内容与声明要返回的函数之间不存在隐式转换。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM