C ++ наследование / шаблон вопроса - PullRequest
5 голосов
/ 12 июля 2010

У меня есть два класса, точка и пиксель:

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

Теперь вот моя проблема. Я хочу создать контейнерный класс (назовем его coll), который имеет собственный вектор точек или пикселей. Если экземпляр coll содержит пиксели, я хочу, чтобы у него был метод toArray (), который преобразует его вектор пикселей в массив T, представляющий содержимое вектора.

Я собирался сделать это с помощью наследования: то есть я мог бы создать базовый класс coll, содержащий вектор точек, и производный класс, содержащий дополнительный метод, но затем я, кажется, столкнулся с проблемами, поскольку pixel - это класс шаблон.

У кого-нибудь есть предложения? Могу ли я сделать это как-нибудь, сделав шаблон класса coll?

Ответы [ 3 ]

3 голосов
/ 12 июля 2010

Вопрос: Вы хотите, чтобы частный вектор содержал одновременно точки и пиксели или только один или другой?

Вопрос: Если один или другой, вы хотите смешатьПиксели с разными параметрами шаблона в одном и том же частном векторе?

Если предположить, что это просто точка или пиксель в частном векторе и что все пиксели в частном векторе имеют один и тот же параметр шаблона, вы можете сделать что-то вродеэто:

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();

    ...

};
1 голос
/ 12 июля 2010

Если collection рассматривает point s и pixel s в основном одинаково и содержит только один или другой, имеет смысл сделать его шаблоном класса.
Относительно 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() доступ.

1 голос
/ 12 июля 2010

Если вы хотите проверить, является ли объект point также типом pixel<T>, вы можете просто увидеть, возвращает ли dynamic_cast NULL.Для этого point должен быть полиморфным, поэтому добавьте в него виртуальный деструктор.

Вот пример:

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<point *> точкой илипиксели.Но для того, чтобы сделать это, вам нужно знать, какая специализация пикселя хранится (т.е. это pixel<int> или pixel<float>?)

Может быть проще сделать coll aвместо этого шаблон класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...