Вопрос о наследовании/шаблоне C++

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

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 представление содержания вектора.

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

У кого-либо есть предложения? Я мог сделать это так или иначе путем создания колледжа шаблоном класса?

5
задан amc 12 July 2010 в 15:35
поделиться

3 ответа

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

    ...

};
3
ответ дан 14 December 2019 в 18:55
поделиться

Если коллекция обрабатывает точек и пикселей в основном одинаково и содержит только один или другой, это имеет смысл чтобы сделать его классом-шаблоном.
Что касается 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
ответ дан 14 December 2019 в 18:55
поделиться

Если вы хотите проверить, является ли объект 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 шаблоном класса.

1
ответ дан 14 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: