问题描述
我正在尝试声明并使用通用帮助函数进行递归。
问题是,我无法触摸默认的头文件。
我们可以链接默认头文件并将实现添加到另一个头文件中,但是,我不知道如何在默认情况下声明的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 ++中使用原始指针(除非您有充分的理由)。这是现代方式。将原始指针传递给函数是唯一仍然有意义的地方,因为这意味着它是可选的(因此应反映在函数内部)。