在Java中,容器有一个详细的通用类层次结构。 Java定义了诸如ICollection< T>之类的接口。由ISet< T>继承的由IList< T>继承的并由ArrayList< T>实现。我想在我正在创建的C ++库中创建一个类似的层次结构。
然而,使用C ++模板会使这非常麻烦。例如,假设我定义了一个ISet< T>:
template<typename T>
class ISet
{
public:
virtual ~ISet() = 0;
virtual void add(T e) = 0;
virtual size_t size() = 0;
virtual bool isEmpty()
{
return size() == 0;
}
};
然后,如果我想制作一个List&lt; T&gt;它实现了ISet&lt; T&gt;,我必须在类定义中列出我想继承但不覆盖的每个方法,以便让我稍后调用它而不会像alist :: ISet&lt; T&gt; - &gt; isEmpty这样凌乱():
template<typename T>
class List : public ISet<T>
{
public:
...
void add(T e)
{
...
}
virtual sz size()
{
...
}
using ISet<T>::isEmpty; //well this is annoying
};
我理解这个的原因,并且“为什么这不能像我期望的那样工作?”已在以下问题中回答:here和here。
我的问题是,是否有一种干净的(甚至任何!)方式来实现这一点,而无需在基类中明确列出每个继承但未覆盖的方法?
我真正想要的是我可以放入List&lt; T&gt;像:
using ISet<T>::*;
将使ISet&lt; T&gt;中的所有方法成为可能。依赖于List&lt; T&gt;的类定义,并将它们别名为List&lt; T&gt; :: functionName。
请告诉我有 SOME 方法来实现这一点,而不必每次更改我的一个模板化接口时更新每个继承类的using指令列表!
我是否必须使用预处理器定义使用与接口一起定义的指令? Arrrrgghhhh!
答案 0 :(得分:1)
此声明不正确:
...必须在类定义中列出我的每个方法 我想继承而不是覆盖,以便让我以后称之为 没有凌乱的东西像alist :: ISet-&gt; isEmpty():
尝试编译以下代码:
template<class T>
class Base {
public:
virtual void f1();
virtual void f2();
};
template<class T>
class Derived : public Base<T> {
public:
virtual void f1();
};
void foobar()
{
Derived<int> d;
d.f1();
d.f2();
}
如果您想要在派生类上访问基类方法或成员,则可以更明确地执行此操作:
template<class T>
class Derived : public Base<T> {
public:
virtual void f1() { this->f2(); }
};
这不是很混乱,而是按照你的要求工作,只是更明确一些(有些人说总是明确地使用this->
是个好主意。)