我正在尝试制作一个继承自的二进制树类Tree
和搜索树的二进制类,以及每个继承自的嵌套类。BST
Tree
iterator
BST::iterator
Tree::iterator
现在的问题是,一些树的功能必须返回iterator
自己的类,如begin()
,end()
,search(T)
等,这似乎不能编译,因为Tree::begin()
和BST::begin()
有‘无效的协变返回类型’。
在研究了上述主题之后,我了解了导致编译器抱怨的原因,但是我不明白为什么不允许这样做。例如,在这种情况下,Tree
应该返回类型的对象Tree::iterator
而BST
应该返回类型的对象似乎是合乎逻辑的BST::iterator
。
以下是一些代码,应说明我正在处理的内容。
template <class T>
class Tree {
protected:
class Node {
friend Tree;
T value;
Node* left;
Node* right;
};
Node* root;
public:
class iterator {
friend Tree;
Node* node;
public:
// operators and the like...
};
virtual iterator begin() const;
virtual iterator end() const;
virtual iterator search(const T& value) const;
};
#include "Tree.h"
template <class T>
class BST : public Tree<T> {
protected:
class Node : public Tree<T>::Node {
friend BST;
};
using Tree<T>::root;
public:
class iterator : public Tree<T>::iterator {
friend BST;
};
using Tree<T>::begin;
using Tree<T>::end;
virtual iterator search(const T& value) const override;
};
对我来说很明显,在这种情况下,搜索试图返回a BST<T>::iterator
,而这是不允许的,因为它覆盖了返回a的函数Tree<T>::iterator
,但是在我看来应该允许这样做,并且我不确定如何应该做到这一点。
另外,当BST<T>
继承begin()
and时end()
,我假设它继承了它们,以便它们返回Tree<T>::iterators
,尽管它们确实应该返回BST<T>::iterators
。
多态只能通过指针/引用来完成,允许返回对象的协方差会引入切片。
我们既不能向“无关”类型添加协方差关系作为智能指针。(而Base*
和Derived*
可以是协变的,std::unique_ptr<Base>
而std::unique_ptr<Derived>
不能:/)
协方差可以通过指针/引用来完成。
解决这些限制的一种方法是使用2种方法,一种是带有支持协方差的虚拟方法,另一种是使用虚拟方法来模拟协方差的常规方法:
template <typename T>
class Tree {
// ...
// Assuming iterator might be constructed with node.
typename Tree<T>::iterator begin() const { return {node_begin()/*, ...*/}; }
typename Tree<T>::iterator end() const { return {node_begin()/*, ...*/}; }
protected:
virtual typename Tree<T>::node* node_begin() const;
virtual typename Tree<T>::node* node_end() const;
};
template <class T>
class BST : public Tree<T> {
// ...
typename BST<T>::iterator begin() const { return {node_begin()/*, ...*/}; }
typename BST<T>::iterator end() const { return {node_begin()/*, ...*/}; }
protected:
typename BST<T>::node* node_begin() const override; // covariance on pointer
typename BST<T>::node* node_end() const override; // covariance on pointer
};
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句