2012-04-06 6 views
2

То, что я пытаюсь сделать, - это вернуть ForwardIterator (или даже пару начинающих и конечных итераторов), чтобы исключающая реализация могла скрываться от класса клиента. Мне не удалось найти такой пример.Скрытие реализации контейнера STL путем возврата итератора

Если базовая реализация является вектором, то итератором является вектор :: итератор .. Даже если вы templatize выход, это, похоже, не работает.

+1

Что значит «не работает»? Пожалуйста, уточните. – larsmoa

+0

Можете ли вы показать код. Трудно догадаться, что случилось с вашим описанием – plaisthos

ответ

2

Вы не можете одновременно возвращать объект как есть и ожидать, что вызывающий абонент не узнает его тип. Типичный способ «скрыть» реальный тип любого объекта - скрыть его за интерфейсом.

Например, вы можете захотеть, чтобы написать что-то вроде этого:

template<typename T> 
class Cursor 
{ 
public: 
    typedef T value_type; 
    virtual ~Cursor() {} 
    virtual bool has_result() = 0; 
    virtual value_type get_result() = 0; 
}; 

// implements cursor interface for any sequence 
// described as a pair of forward iterators. 
template<typename I> 
class ForwardSequenceCursor : 
    public Cursor<std::iterator_traits<I>::value_type> 
{ 
    I myCurrent; 
    const I myEnd; 
public: 
    ForwardSequenceCursor(I begin, I end) 
     : myCurrent(current), myEnd(end) 
    {} 
    virtual bool has_result() { 
     return myCurrent != myEnd; 
    } 
    virtual value_type get_result() { 
     return *myCurrent++; 
    } 
}; 

Затем, вы можете вернуть любой прямой последовательности, как:

class Foo 
{ 
    std::vector<int> myValues; 
public: 
    std::unique_ptr< Cursor<int> > values() { 
     return std::unique_ptr< Cursor<int> >(
      new ForwardSequenceCursor<vector<int>::const_iterator>(
       myValues.begin(), myValues.end() 
      ) 
     ); 
    } 
}; 

И использовать его так:

std::unique_ptr< Cursor<int> > cursor = foo.values(); 
while (cursor->has_result()) { 
    std::cout << cursor->get_result() << std::endl; 
} 
0

ForwardIterator - это концепция, а не тип. Вам нужно объявить вашу функцию для возврата типа.

0

Там нет базового класса типа «ForwardIterator», нормальный STL способ иметь ЬурейеЕ до фактического типа итератора в вашей чтобы код клиента мог использовать его следующим образом:

MyClass :: iterator it = myclass.begin();

Не очень хорошо, как скрывается, но по-прежнему позволяет вам изменить реализацию позже без изменения кода клиента.

1

Вы не можете напрямую делать то, что вы пытаетесь сделать, потому что, как упомянули другие, если ваш клиент goin g, чтобы получить возвращаемое значение, ему нужно знать, что это за возвращаемое значение.

Один из способов вокруг него, чтобы сделать что-то вроде этого:

template<typename Collection> class MyClass 
{ 
    typedef Collection::iterator ReturnIt; 
    typedef std::pair<ReturnIt, ReturnIt> IteratorPair; 
    ReturnIt foo(); 
    IteratorPair bar(); 
}; 

Теперь, это не освобождает нас от клиентов видящих контейнерного типа, но интерфейс не связан с типом контейнера.