【问题标题】:Why passing a pointer by reference here causes an error?为什么在这里通过引用传递指针会导致错误?
【发布时间】:2020-12-17 05:33:42
【问题描述】:

我有一个模板节点类:

template<typename T>
class TNode {
    T data;
    TNode<T>* left;
    TNode<T>* right;
public:
    TNode() {   left = right = nullptr; }
    TNode(T d) {    data = d;   left = right = nullptr; }
    void setData(T d) { data = d; }
    T getData() {   return data;    }
    void setLeft(TNode<T>* l) {     left = l;   }
    TNode<T>* getLeft() {   return left;    }
    void setRight(TNode<T>* r) {    right = r;  }
    TNode<T>* getRight() {  return right;   }
};

我用来构建以下二叉搜索树:

template<typename T>
class BSTree
{
private:
    TNode<T>* root;
    void rec_insertBST(TNode<T>*& subRoot, int key)
    {
        if (subRoot == nullptr)
            subRoot = new TNode<T>(key);
        else if (subRoot->getData() < key)
            rec_insertBST(subRoot->getRight(), key);
        else
            rec_insertBST(subRoot->getLeft(), key);
    }
public:
    void insertBST(int key)
    {
        rec_insertBST(root, key);
    }
};

当我通过引用 (&) 将指针传递给插入函数时,我收到此编译错误:

'void BSTree::rec_insertBST(TNode *&,int)': 无法转换 参数 1 从 'TNode *' 到 'TNode *&'

但是当我删除引用运算符 (&) 时,它编译成功。为什么会发生这种情况,如何在这里通过引用传递指针?

即使代码没有意义,我也想解释一下错误。

【问题讨论】:

  • 为什么要通过引用传递指针?通过指针或引用传递...
  • 您不能将非常量引用绑定到临时引用。从 getter 返回引用或使用公共成员。 (Here 是一篇关于此类“准类”的有趣文章。)
  • @OffensiveRook so the getters are returning copies.. that's the reason? I didn't expect compiler to be that smart .. 只要您的返回中没有&amp;,c++ 总是会返回您返回的内容的副本。因此,在您的情况下,将返回 TNode&lt;T&gt;* 指针的副本。 (T getData() 也是如此,其中返回了 T 的副本。
  • @OffensiveRook:那么,也许告诉你的导师教你标准库已经提供的东西,以及如何有效地使用它,而不是教你重新发明轮子。 ;-) 而且 如果 你的导师让你创建一个容器类,它应该“看起来”像一个 C++ 容器,而不是 Java 容器...... ;-) (无意冒犯你或你的导师。我刚刚看到太多这样的“重新实现标准”作业,它们真的不教应用程序或库编码人员应该教什么...)
  • @DevSolar 同意。你完全正确。

标签: c++ pointers templates


【解决方案1】:

getLeft 方法返回left 成员变量的副本,因此即使您的代码编译它也不会改变left。但是由于不能将引用绑定到临时对象的规则,它无法编译。

有几种可能的解决方案,对我来说最好的一个是将getLeft 替换为leftgetRight 替换为right

       rec_insertBST(subRoot->right, key);

这将需要更改访问权限或授予友谊。

另一种选择是让getLeftgetRight 返回引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 2014-10-15
    • 1970-01-01
    相关资源
    最近更新 更多