C++ 不带模板的虚拟typedef的替代方案
编辑的较短问题: 当使用指向抽象类的指针时,如何调用它所指向的对象的实际类型的方法 我有一个抽象的C++ 不带模板的虚拟typedef的替代方案,c++,templates,inheritance,iterator,C++,Templates,Inheritance,Iterator,编辑的较短问题: 当使用指向抽象类的指针时,如何调用它所指向的对象的实际类型的方法 我有一个抽象的BaseTree类,带有一个公共 virtual BaseTree const& operator[](NodeIndex const& poss) const = 0; 其中,NodeIndex实际上是std::vector。我还有一个TreeBasicIterator类,其中包括 public: /// Access the tree to which m_tree p
BaseTree
类,带有一个公共
virtual BaseTree const& operator[](NodeIndex const& poss) const = 0;
其中,NodeIndex
实际上是std::vector
。我还有一个TreeBasicIterator
类,其中包括
public:
/// Access the tree to which m_tree points
BaseTree& operator*() const
{
//checking...
return (*m_tree)[*this];
}
private:
/// the tree the current iterator refers to
BaseTree* m_tree=nullptr;
问题(我认为这是我下面最初问题的关键):
如何使用与*m_树的实际类型对应的类的方法?现在,当取消对迭代器的引用时,我只能使用抽象类BaseTree
的方法
我希望避免将TreeBasicIterator
作为模板(参见下面的初始问题)
初始问题
< C++ >(相对较新的)用户,我想写< /P>
virtual typedef something my_virtual_type;
类内定义。不幸的是,这是不可能的
最流行的替代方案似乎是模板,例如,其中提供了一个很好的总结
然而,我不确定它涵盖了虚拟typedef的所有内容。我在下面提出一个问题,我希望使用虚拟typedef。我有一个(临时的?)工作解决方案,使用重载而不是模板
我想创建一个奇特的树结构,包括迭代器
1) 我定义了一个NodeIndex
类型,它是我未来迭代器的祖先。(NodeIndex
在我的例子中是std::vector
,但这并不重要。)
2) 我定义了一个抽象的BaseTree
类,在下面的迭代器中使用。该类特别包括返回要在树中移动的NodeIndex
索引的虚拟方法(例如NodeIndex begin()
),以及运算符[](NodeIndex const&)
3) 我定义了一个TreeBasicIterator
类,继承自NodeIndex
,出于一致性目的,该类包括对BaseTree
的常量引用,并实现了各种迭代器方法(利用BaseTree
提供的虚拟方法)
(我实际上有两个类:treebasicierator
,和Const\u treebasicierator
,其中Const引用了Const BaseTree
;我使用预处理器宏模拟基于Const的模板,但这是另一个问题。)
4) 我已经定义了一个TreeNode
模板类(T
是节点内容),继承自BaseTree
。现在,它的begin()
方法返回一个NodeIndex
,它的操作符[]
将一个NodeIndex
作为参数,一切正常
5) 但是,我想在我的TreeNode
类中包含我的TreeBasicIterator
。我想包括一个
virtual typedef NodeIndex Iterator;
virtual typedef TreeBasicIterator Iterator;
在我的BaseTree
类中,将虚拟begin()
方法签名修改为Iterator begin()
。
然后TreeNode
将包含一个
virtual typedef NodeIndex Iterator;
virtual typedef TreeBasicIterator Iterator;
它的begin()
方法签名将是Iterator begin()
,
希望一切都会好起来:)
6) 我不希望在TreeBasicIterator
上使用模板:它现在是一次性编译的
制作BaseTree
模板将使TreeBasicIterator
成为模板,从而失去了BaseTree
中抽象的一部分好处
用NodeIndex
作为Iterator
类型实例化BaseTree
是多余的:实际上没有人会从该特定实例继承
7) 预期:
我将使用结构固定或很少修改的树,但更频繁地修改节点内容,甚至更频繁地进行读取访问。为了优化访问,我打算进一步从TreeNode
aTreeVector
类派生,该类将包括NodeIndex
(或BasicTreeIterator
?)索引的排序穷举std::vector
)。TreeVector
中的Iterator
虚拟类型将是std::Iterator
8) 当前(临时?)部分工作解决方案:
TreeNode
定义(通过一个常用的typedef
)一个Iterator
类型(mytreebasicaterator
类)。它不会覆盖BaseTree
中的迭代器类型,但它可以
BaseTree
有一个NodeIndex begin()const
方法,该方法既不隐藏,又通过迭代器begin()const
方法在TreeNode
中重载。它不会被覆盖
类似地,我在BaseTree
中有一个NodeIndex next_index(NodeIndex)const
,它既不隐藏,又通过迭代器next_index(迭代器)const
方法在树节点中重载。。。无论如何,这里是我的工作解决方案:混合模板类和非模板类
TreeBasicIterator
仍然是问题中解释的非模板类
dynamic_cast
是在其BaseTree
指针上调用树类特定方法的工具。但是,每次在代码中取消对迭代器的引用时都必须使用它是不合理的
我派生一个模板TreeIterator
类:
template<class MyTree> class TreeIterator: public TreeBasicIterator
当所做的事情独立于所使用的实际树类时,将调用TreeBasicIterator
的一次性编译方法。C++不能以这种方式工作。故事结束。@Sam:我知道。我在寻找一个可能比我在我的观点中所提出的解决方案更有效的替代方案,因为我是新来的,也许解释否决票的评论会对我有所帮助