访问祖父母虚拟方法
Access grandparent virtual method
我有三个类:
template<typename E>
class Iterator {
public:
virtual ~Iterator() {
}
virtual bool hasNext() const = 0;
virtual const E& next() = 0;
};
template<typename E>
class IteratorPtr {
private:
Iterator<E>* iterator;
IteratorPtr(const IteratorPtr<E>&);
IteratorPtr<E>& operator=(const Iterator<E>&);
public:
IteratorPtr(Iterator<E>* it)
: iterator(it) {
}
~IteratorPtr() {
delete iterator;
}
Iterator<E>* operator->() const {
return iterator;
}
};
template<typename E>
class Collection
{
public:
virtual void add(const E & value) = 0;
virtual void add(const Collection<E>& collection);
virtual bool remove(const E& value) = 0;
virtual void clear() = 0;
virtual ~Collection()
{
}
virtual bool isEmpty() const = 0;
virtual int size() const = 0;
virtual bool contains(const E& value) const = 0;
virtual Iterator<E>* iterator() const = 0;
};
void Collection<E>::add(const Collection<E>& collection)
{
for (IteratorPtr<E> i(collection.iterator()); i->hasNext();) {
this->add(i->next());
}
}
对象:所有Set的方法都被实现。
template<typename E>
class Set;
template<typename E>
class SortedSet;
template<typename E>
class SetIterator;
template<typename E>
class SetNode {
private:
friend class Set<E> ;
friend class SortedSet<E> ;
friend class SetIterator<E> ;
SetNode()
: next(NULL) {
}
SetNode(E value)
: value(value), next(NULL) {
}
SetNode(E value, SetNode * next)
: value(value), next(next) {
}
~SetNode() {
}
private:
E value;
SetNode * next;
};
template<typename E>
class SetIterator: public Iterator<E> {
private:
friend class Set<E> ;
SetIterator(SetNode<E> * head)
: node(head) {
}
~SetIterator() {
}
bool hasNext() const {
return node != NULL;
}
const E & next() {
E& value = node->value;
node = node->next;
return value;
}
private:
SetNode<E> * node;
};
template<typename E>
class Set: public Collection<E> {
public:
Set(): numNodes(0), head(NULL) {
}
virtual ~Set() {
clear();
}
virtual void add(const E & value);
virtual bool remove(const E& value);
virtual void clear();
virtual bool isEmpty() const;
virtual int size() const;
virtual bool contains(const E& value) const;
virtual Iterator<E>* iterator() const;
private:
Set(const Set & obj): numNodes(0), head(NULL) {
}
virtual bool contains(const E & value, SetNode<E> * & previ) const;
protected:
int numNodes;
SetNode<E> * head;
};
template<typename E>
class SortedSet: public Set<E> {
private:
virtual bool contains(const E& value, SetNode<E> *& prev) const;
public:
SortedSet(): Set<E>() {
}
virtual void add(const E & value);
virtual ~SortedSet() {
this->clear();
}
};
Set和SortedSet不实现add方法,因为它们应该做的正是Collection::add(const Collection&c)。
int main() {
Set<int> *s = new Set<int>();
s->add(10);
s->add(30);
s->add(12);
s->remove(10);
if (s->contains(30))
puts("Tem");
SortedSet<int> *ss = new SortedSet<int>();
ss->add(*s);
return 0;
}
但这段代码在"ss->add(*s);"行中出现错误,说:与' SortedSet::add(Set&) '不匹配
为什么会发生这种情况?
现在您已经发布了所有相关代码,问题是您已经在Set
中声明了另一个同名函数:
virtual void add(const E & value);
隐藏基类中同名的所有内容;所以Collection::add
不能通过引用Set
或它的任何子类来访问。
要解决这个问题,向Set
添加一个using声明,将Collection::add
纳入Set
的作用域:
public:
using Collection::add;
相关文章:
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在模板基类中为继承类中的可选重写生成虚拟方法
- 跨 DLL 边界访问虚拟方法是否安全/可能?
- 是否可以使用基类非虚拟方法中的派生类虚拟方法?
- 如何编写 operator= 用于使用虚拟方法与非平凡成员的匿名联合
- 让编译器告诉什么确切的纯虚拟方法使结构抽象?
- 使用模板而不是虚拟方法的管道模式
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 从纯虚拟类 (A) 派生的指针无法访问来自纯类 (B) 的重载方法
- 为什么调用没有正文的纯虚拟方法不会导致链接器错误?
- 出于什么目的,非虚拟方法将与C++一起使用?
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?
- 如何重写继承的嵌套类中存在的虚拟方法
- 私有虚拟方法有什么用?
- 派生类中纯虚拟基方法的专业化
- 基类可以声明虚拟方法但不定义它吗?仍然在派生类中定义
- googletest:测试基类具有纯虚拟方法的派生类时的核心转储
- 确保模拟的 GTest 方法覆盖虚拟方法
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 如何调用孩子的方法:虚拟关键字不起作用