У меня есть два класса, точка и пиксель:
class point {
public:
point(int x, int y) : x(x), y(y) { };
private:
int x, y;
}
template <class T>
class pixel : public point {
public:
pixel(int x, int y, T val) : point(x, y), val(val) { };
private:
T val;
}
Теперь вот моя проблема. Я хочу сделать контейнерный класс (давайте назовем его колледжем), который имеет частный вектор точек или пикселей. Если экземпляр колледжа содержит пиксели, я хочу, чтобы он имел метод toArray (), который преобразовывает его вектор пикселей к массиву T представление содержания вектора.
Я собирался сделать это с наследованием: т.е., я мог заставить базовый класс стричь, который содержит вектор точек и производного класса, который содержит дополнительный метод, но затем я, кажется, сталкиваюсь с проблемами, так как пиксель является шаблоном класса.
У кого-либо есть предложения? Я мог сделать это так или иначе путем создания колледжа шаблоном класса?
Question: Вы имеете в виду, чтобы частный вектор содержал одновременно и точки, и пиксели, или только одно или другое?
Вопрос: Если только одно или другое, вы имеете в виду смешивать пиксели с разными параметрами шаблона в одном частном векторе?
Предполагая, что в приватном векторе только Point или Pixel, и что все Pixels в приватном векторе имеют одинаковый параметр шаблона, вы можете сделать что-то вроде этого:
template < class T > class CollectionBase
{
//common interface here
protected:
std::vector<T> coll_vec;
};
class PointCollection : public CollectionBase<Point>
{
public:
...
};
template< class T> PixelCollection : public CollectionBase<Pixel<T> >
{
public:
Pixel<T>* toArray();
...
};
Если коллекция
обрабатывает точек
и пикселей
в основном одинаково и содержит только один или другой, это имеет смысл чтобы сделать его классом-шаблоном.
Что касается to_array
, то было бы проще сделать ее бесплатной функцией:
template<class T> struct collection {
std::vector<point<T> > data_;
// ...
};
template<class T>
void to_array(const collection<point<T> >& in, point<T>* out) {
// ...
}
Обратите внимание, что вам придется предоставить общий интерфейс для чтения и доступа к данным, однако или, по крайней мере, выборочно предоставить to_array ()
доступ.
Если вы хотите проверить, является ли объект point
также типом pixel
, то вы можете просто посмотреть, возвращает ли dynamic_cast
] NULL
. Для этого точка
должна быть полиморфной, поэтому добавьте к ней виртуальный деструктор.
Вот пример:
point x(0, 0);
pixel<int> y(0, 0, 0);
point *pX = &x;
point *pY = &y;
if(dynamic_cast<pixel<int> *> (pX) != NULL) {
std::cout << "x is a pixel<int>.";
}
if(dynamic_cast<pixel<int> *> (pY) != NULL) {
std::cout << "y is a pixel<int>.";
}
Результат будет следующим:
y - пиксель
.
Вы можете использовать этот код в своем классе coll
, чтобы проверить, является ли каждый элемент вектора vector
точкой или пикселем. Но для этого вам нужно знать, какая специализация пикселя сохраняется (т.е. pixel
или pixel
?)
Может быть проще сделать coll
шаблоном класса.