C ++:如何实现需要访问类的受保护成员而不更改头文件的私有帮助器功能?

问题描述

我正在尝试声明并使用通用帮助函数进行递归。
问题是,我无法触摸认的头文件
我们可以链接认头文件并将实现添加到另一个文件中,但是,我不知道如何在认情况下声明的Node类中添加更多功能而不会发生重定义错误
注意:Node类有吸气剂,而Tree没有设置器。
注意2 :我们只能链接认的头文件,不能添加其他头文件

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

ab = [1,2,1,...,2]
    
numberList = []
        
def numbers(array):
  for a in array:
    if a == 1:
     numberList.append(a)
            
numbers(ab)
print(numberList)

哪个会导致此错误

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

因为标题中没有定义辅助功能
我不能在不更改认标头的情况下声明Node :: insertNode。

如您所见,助手需要访问Node的受保护成员(数据,左,右)。
我尝试将(Node *)作为附加参数作为自由函数传递给帮助器,但是后来我不知道如何仅使用getter来左右设置(头中没有setter函数)。
因此,如果不将其声明为标题中的朋友,则无法将其设置为自由功能,这也是我无法触摸的。

我该怎么办?有建议吗?


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

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

但是我得到:

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

如果我尝试将->更改为。 (例如node.data),那么它只会显示

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

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

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

给我同样的问题:

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

解决方法

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

您可以做什么:

  • 要么创建独立的辅助函数(非成员),然后使用Node的公共接口

  • 为ex创建一个包装器。 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 ++中使用原始指针(除非您有充分的理由)。这是现代方式。将原始指针传递给函数是唯一仍然有意义的地方,因为这意味着它是可选的(因此应反映在函数内部)。