繁体   English   中英

C++:如何在不改变头文件的情况下实现需要访问类的受保护成员的私有帮助函数?

[英]C++: How to implement private helper function that requires access to protected members of a class without altering header file?

我正在尝试声明并使用通用辅助函数来进行递归。
问题是,我无法触摸默认头文件.
我们可以链接默认头文件并将实现添加到另一个头文件中,但是,我不知道如何在没有重新定义错误的情况下向默认声明的类 Node 添加更多函数。
注意:Node 类有 getter,但没有 setter,Tree 也一样。
注2 :我们只能链接默认头文件,不能添加其他头文件。

如果我可以声明助手,我想要什么:

template <class T>
void Tree<T>::add(const T &x){
    if(root){
        root->insertNode(x);
    } else{
        root = new Node<T>(x);
    }
}

template <class T>
void Node::insertNode(T const &x){
    if(x < value){
        if(left){
            left->insertNode(x);
        } else{
            left = new Node<T>(x);
        }
    } else if(x > value){
        if(right){
            right->insertNode(x);
        } else{
            right = new Node<T>(x);
        }
    }
}

这导致此错误:

Out-of-line definition of 'insertNode' does not match any declaration in 'Node<T>'

因为辅助函数未在默认标头中定义。
我无法在不更改默认标头的情况下声明 Node::insertNode。

如您所见,helper需要访问受保护的 Node 成员(数据、左、右)。
我尝试将 (Node*) 作为附加参数作为自由函数传递给帮助程序,但后来我不知道如何仅使用 getter 来设置左右(标题中没有 setter 函数)。
所以我不能在不将它声明为标题中的朋友的情况下将它设置为自由函数,这又是我无法触摸的。

我能做什么? 建议?


编辑:
按照@darune 的建议,我尝试将引用作为参数传递:

template <class Base>
void insertNode(const Base &item, Node<T>& node){
    if(item < node->data){
        if(node->left){
            insertNode(item, node->left);
        } else{
            node->left = new BSTNode<Base>(item);
        }
    } else if(node->data > item){
        if(node->right){
            insertNode(item, node->right);
        } else{
            node->right = new BSTNode<Base>(item);
        }
    }
}

但后来我得到:

error: base operand of '->' has non-pointer type 'Node<int>'
if(item < node->data)

如果我尝试将 -> 更改为 . (如 node.data),然后它只是说:

Node<T>::data is protected within this context

编辑2:
使用模板参数作为参考参数(不确定是否正确):

template <class T, class S>
void insertNode(const Base &item, S& node){
    if(item < node->data){
        if(node->left){
            insertNode(item, node->left);
        } else{
            node->left = new BSTNode<Base>(item);
        }
    } else if(node->data > item){
        if(node->right){
            insertNode(item, node->right);
        } else{
            node->right = new BSTNode<Base>(item);
        }
    }
}

给了我与上述相同的问题:

error: base operand of '->' has non-pointer type 'Node<int>'
if(item < node->data)

根据语言规则,您不能在不修改头文件的情况下添加成员帮助函数。

你可以做什么:

  • 创建独立的辅助函数(非成员)并使用 Node 的公共接口

或者

  • 创建一个包装器,例如。 class NodeWrapper : public Node并使用包装类:

     template <typename T> class NodeWrapper : public Node<T> { void insertNode(const T& x) { ... rest of the code ... ... you can access protected member of Node here, but not the private ones } }

您可以将受保护/私有成员的引用(或指针)传递给需要处理它的函数。 这样你仍然坚持所有的语言和设计原则。 另外一个额外的好处是改进的封装。

就像是:

void insertNode(const auto& x, auto& left, auto& right){

另外,尽量避免在 c++ 中使用原始指针(除非你有充分的理由)。 这是现代方式。 将原始指针传递给函数是唯一仍然有意义的地方,因为这意味着它是可选的(因此应该反映在函数内部)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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