0

在 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;
        }
    };

然后,如果我想创建一个实现 ISet<T> 的 List<T>,我必须在类定义中列出我想要继承但不覆盖的每个方法,以便我以后调用它而不会造成混乱像 alist::ISet<T>->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
};

我理解这样做的原因,并且“为什么这不按我期望的方式工作?” 已在这些问题中得到回答:herehere

我的问题是,是否有一种干净(甚至任何!)的方法来实现这一点,而不必显式列出基类中每个继承但未覆盖的方法?

我真正想要的是可以放入 List<T> 的东西,例如:

using ISet<T>::*;

这将使 ISet<T> 中的所有方法都依赖于 List<T> 的类定义,并将它们别名为 List<T>::functionName。

请告诉我有一些方法可以实现这一点,而无需在每次更改我的模板化接口之一时更新每个继承类的 using 指令列表!

我是否必须求助于使用与接口一起定义的指令的预处理器定义?啊啊啊啊!

4

1 回答 1

1

这种说法是不正确的:

... 必须在类定义中列出我想继承但不覆盖的每个方法,以便我以后调用它而不会像 alist::ISet->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->明确使用是个好主意)。

于 2013-09-25T18:59:43.103 回答