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

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

我正在尝试声明并使用通用辅助函数来执行递归。
问题是,我 无法触及默认的 header 文件
我们可以链接默认的 header 文件并将实现添加到另一个 header 文件,但是,我不知道如何向默认声明的 class 节点添加更多功能而不用重新定义错误。
注意:节点 class 有吸气剂,但没有 setters,树也一样。
注意2:我们只能链接默认的header文件,不能添加其他headers文件。

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

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>'

因为辅助函数没有在默认值中定义 header。
如果不更改默认 header.

,我无法声明 Node::insertNode

如您所见,助手 需要访问 Node 的受保护成员(数据,左,右)。
我尝试将 (Node*) 作为附加参数作为自由函数传递给辅助函数,但后来我不知道如何仅使用吸气剂设置左右([=64= 中没有 setter 函数]).
因此,如果不在 header 中将其声明为好友,我就无法将其设置为自由函数,同样,我无法触及。

我能做什么?建议?


编辑:
按照@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)

根据语言规则,不修改头文件就不能添加成员辅助函数。

你可以做什么:

  • 创建独立的辅助函数 (non-member) 并使用 Nodepublic 接口

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

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

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

类似于:

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

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