抽象类中的嵌套类

时间:2014-03-11 09:23:46

标签: c++ abstract-class inner-classes nested-class

我有一个像这样的抽象类:

class A
{
public:
    void func() = 0;
};

我可以强制它的实现也有一个嵌套的迭代器类吗?

#include <iterator>

template<typename T>
class A
{
public:
    class Iterator : public std::iterator<std::forward_iterator_tag, T>
    {
    };

    virtual Iterator begin() const = 0;
    virtual void func() = 0;
};

template<typename T>
class B : public A<T>
{
public:
    B() {}
    class Iterator : public std::iterator<std::forward_iterator_tag, T>
    {
    };

    Iterator begin() const
    {
        return Iterator();
    }

    virtual void func()
    {
    }
};

int main()
{
    B<int> b;
}

我只是想知道这是否可能,如果是的话,我错过了什么?由于迭代器类将取决于如何实现类A,我不知道是否可以正式实现。

2 个答案:

答案 0 :(得分:4)

试试这个:

template<typename T>
class A
{
public:
    class Iterator : public std::iterator<std::forward_iterator_tag, T>
    {
    public:
        virtual void DoSomething() = 0;
    };

    virtual Iterator * begin() const = 0;
    virtual void func() = 0;
};

template<typename T>
class B : public A<T>
{
public:
    B() {}
    class BIterator : public A<T>::Iterator
    {
    public:
        void DoSomething()
        {
            std::cout << "Hello world from B::BIterator!";
        }
    };

    A<T>::Iterator * begin() const
    {
        return new BIterator();
    }

    virtual void func()
    {
    }
};

int main(int argc, char * argv[])
{
    B<int> b;

    A<int>::Iterator * iter = b.begin();
    iter->DoSomething();
    delete iter;

    getchar();
}

请注意,这不会强制 B实现A<T>::Iterator的新实例,而只是提供一个实例。例如,Developer可以实现一个通用迭代器,并从所有A<T>派生类中返回它。但我想,这应该够了,不应该吗?


编辑:回应评论

您应该通过指针返回迭代器。由于您希望它是一个抽象类,因此您无法声明它的实例:

A<int>::Iterator iter = b.begin(); // Error: cannot instantiate abstract class
                                   // A<int>::Iterator

如果你辞去A<T>::Iterator作为抽象类,你可以这样做。但是,你将不能强迫一个人从A<T>::Iterator下降......

答案 1 :(得分:1)

  

我只是想知道这是否可能,如果是,我错过了什么?

嗯,不,除非你为Iterator定义至少一个纯虚拟成员函数,否则你不能强制派生类有一个。

标准库解决此问题的方法是使用 concepts 。它们是模板参数上的约束,后者又定义了公共对象的公共接口。

Container concept为例:它要求通用类型T具有以下有效表达式:

  • ...
  • T::reference
  • T::const_reference
  • T::iterator
  • ...

通过这种方式,您可以定义一个函数:

template<class Container>
void do_something(Container c) {
    Container::iterator it = c.begin();
    // etc
}

并期望它适用于符合Container概念的每种类型。实际上,上面的代码happily compiles使用了3个不同的标准容器(即vectorlistdeque)。

通过这种方式,作为C ++用户,您可以创建自己的容器,使其符合您要支持的概念要求,并能够自动使用任何其他容器所具有的所有算法。不需要任何接口,没有公共继承,没有。

更不用说现在正在讨论一个明确的Concept Lite proposal,以更明确的方式实现这些“ interfaces ”。