如何返回智能指针?

时间:2012-05-02 14:19:22

标签: c++ c++11 smart-pointers

我有一个键,一个指向结构中定义的左右节点的指针,位于二叉搜索树的类中。

我在类的复制助手函数中遇到了parasoft错误,因此建议将代码更改为:

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;
    }
}

现在我在newNode的return语句中收到错误:

  

IntelliSense:从NodePtrBinaryTree::Node *

没有合适的转换功能

任何想法?

4 个答案:

答案 0 :(得分:3)

AHAH。您无法将unique_ptr<T>转换为T*。它们不是同一类型,并且它们没有相同的语义,特别是当它们被复制时。这就是unique_ptr<T>没有转化运算符T*的原因。 T*不是一个类,因此您不能依赖多态来为您完成工作,就像返回声明的返回类型的子类(实际上unique_ptr的语义差异一样意味着子类化无论如何都是错误的关系。)

所以你在这里没有选择 - 你必须返回unique_ptr<T>并让你的来电者处理后果,因为他们需要知道它是unique_ptr<T>并且表现得像一个。如果您认为这是一个太大的负担,我建议您阅读智能指针,以更好地了解它们是什么以及它们为您做了什么。

您可能还需要考虑它是否是正确类型的智能指针类,因为shared_ptr<T>可能有更适合您的语义。

答案 1 :(得分:3)

如果我理解它copyHelper是一个内部函数,而不是接口的一部分。如果是这样,那么最简单的解决方案是更改签名以返回unique_ptr而不是原始指针。

另一种方法是在release unique_ptr内调用copyHelper放弃所有权,然后让调用者在其自己的unique_ptr中回收它(为此您需要)使用reset),但是当你要在下一步中将它存储在unique_ptr时,没有必要通过原始指针。

答案 2 :(得分:2)

这是你的功能:

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

它返回BinaryTree::Node*,它应该返回unique_ptr<Node>

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

答案 3 :(得分:1)

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