【问题标题】:How to return a smart pointer?如何返回智能指针?
【发布时间】:2012-05-02 14:19:22
【问题描述】:

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

我在类的复制辅助函数中遇到 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 * 的转换函数

有什么想法吗?

【问题讨论】:

  • 您能否检查一下您的代码示例,目前您对newNode 的定义无法编译。
  • unique_ptr 的 ctor 是显式的
  • 您要返回什么,unique_ptr&lt;Node&gt;Node*?如果你想要 Node*,那么它不需要在你的函数中有 NodePtr。
  • 我以前用过Node* newNode = new Node;但被告知要使用新的代码stackoverflow.com/questions/10414869/… 我仍然想返回我之前返回的内容,但使用智能指针代替。
  • 您似乎不明白为什么需要智能指针并尝试这样做是因为互联网上的某人告诉了您。他们告诉你的恰好是很好的建议,但如果你了解为什么这是很好的建议,你可能就不需要问这个问题了。

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


【解决方案1】:

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

所以你在这里别无选择 - 你必须返回一个 unique_ptr&lt;T&gt; 并让你的调用者处理后果,因为他们需要知道它是一个 unique_ptr&lt;T&gt; 并且表现得像一个。如果您觉得这负担过重,我建议您阅读智能指针,以更好地了解它们是什么以及它们为您做了什么。

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

【讨论】:

  • 您无法将 unique_ptr&lt;T&gt; 转换为 T*。虽然你不应该你显然可以。没有转换,但unique_ptr&lt;T&gt; 有一个release 成员函数,它将产生指针的所有权。话虽如此,您是否愿意这样做是一个完全不同的问题。
  • 这就是为什么我没有将其称为转换。
【解决方案2】:

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

替代方法是在copyHelper 内的unique_ptr 上调用release 以放弃所有权,并让调用者在它自己的unique_ptr 中收回它(为此,您需要使用reset),但是当您要在下一步将原始指针存储在unique_ptr 中时,通过原始指针是没有意义的。

【讨论】:

  • 谢谢,我已经更改了它,但是由于我的所有其他函数都需要一个原始指针,它产生了更多错误。我想我会在我的解决方案中留下我的两个 parasoft 错误,在可能的 100 分中,我只丢了两个分数。
  • @LewisElliott 如果您发现有用的答案,您也可以投票。我在这里看到很多有用的答案...
  • 它们很有用,但我还没有 15 声望,我是新手。所以我不能投票。
【解决方案3】:

这是你的功能:

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

它返回一个BinaryTree::Node*,它应该返回一个unique_ptr&lt;Node&gt;

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 2014-05-30
      • 1970-01-01
      • 1970-01-01
      • 2015-06-12
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 2010-11-01
      • 1970-01-01
      相关资源
      最近更新 更多