2014-09-01 3 views
0

say У меня есть два типа матриц: рег и разреженный. Я создал абстрактный класс отца «Матрица», а два выше наследуются от «Матрицы». Я хочу создать абстрактный итератор, чтобы «MatrixIterator» был отцом абстрактного класса, и «RegMatrixIterator», «SparseMatrixIterator» наследует от него. всего 6 классов.Создание абстрактной обертки итератора

RegMatrix содержит векторное представление, а SparseMatrix содержит карту, которая отображает между парами индексов и значением.

Каков наилучший способ реализации итераторов?

+0

Почему бы вам не просто использовать std :: vector и перебрать это? –

+0

, потому что я сам реализую оба типа. –

+1

Итераторы не очень хорошо работают с полиморфизмом. см. здесь http://www.artima.com/cppsource/type_erasure.html –

ответ

1

iterator - это общий механизм, абстрагирующий детали того, как элементы фактически хранятся. Поскольку общее ориентированное на объект программирование (ООП) не очень хорошо работает вместе, итераторы обычно не реализуются через ООП.

Я не знаю, почему вы хотите использовать ООП для вас Matrix, т. Е. Действительно ли вы хотите использовать полиморфизм во время выполнения на матрицах. Если это действительно важно, тогда вам понадобятся полиморфные Matrix::begin() и Matrix::end() и, следовательно, потребность в полиморфном Matrix::iterator. Код с использованием таких матриц будет выглядеть

#include <Matrix.hpp> 
void foo(Matrix const&m) 
{ 
    for(a : m) { [...] } 
} 

Но вы будете платить цену вызова виртуальной функции (виртуальная таблица взгляд вверх) для каждого вызова полиморфного метода Matrix::iterator. Если это не критично для производительности, этот тип дизайна в порядке, хотя и необычен для итераторов.

Однако я бы предпочел общий подход к программированию, в соответствии с которым два типа матриц могут быть получены из общей базы, но не для полиморфизма во время выполнения. Тогда каждый тип просто имеет свой собственный тип итератора и собственный не виртуальный begin() и end(). Код с использованием таких матриц будет выглядеть

#include <Matrix.hpp> 
template<typename Matrix> 
typename std::enable_if<is_Matrix<Matrix>::value>:: // is_Matrix defined in Matrix.hpp 
type foo(Matrix const&m) 
{ 
    for(x : m) { [...] } 
} 

Вместо SFINAE (std::enable_if), вы можете просто static_assert() правильный тип матрицы, хотя тогда ваша функция может быть неоднозначным с другим foo(some_arg).

+0

большое спасибо! это действительно помогло –

Смежные вопросы