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++ 中使用 原始指针(除非您有充分的理由这样做)。这是现代的方式。将原始指针传递给函数是唯一仍然有意义的地方,因为这意味着它是可选的(因此应该反映在函数内部)。
我正在尝试声明并使用通用辅助函数来执行递归。
问题是,我 无法触及默认的 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 的受保护成员(数据,左,右)。
我尝试将 (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++ 中使用 原始指针(除非您有充分的理由这样做)。这是现代的方式。将原始指针传递给函数是唯一仍然有意义的地方,因为这意味着它是可选的(因此应该反映在函数内部)。