У меня есть вершина абстрактного класса, которая представляет n-кортеж. Элемент вершины может иметь любой тип: т.е., компоненты вершины могли иметь интервал типа, интервал, плавание или что-то. Поскольку вершина может иметь произвольное число размеров, я думал о том, чтобы заставлять класс иметь метод set компонента как так:
class vertex {
public:
template <class T>
virtual void setComp(int componentnumber, T value) = 0;
};
Конечно, C++ не разрешает шаблоны виртуальной функции. Так: как я должен делать это? Я также не знаю, как я должен писать метод считывания для вершин.
Спасибо.
Ну, обычно у вас должен быть тип вершины в качестве параметра шаблона, чтобы его можно было правильно сохранить:
template<typename T, size_t NumAxes = 3>
class vertex {
private:
T comp[NumAxes];
};
В этом случае нет необходимости в виртуальном методе, поскольку вы можете просто использовать приведение типов C ++ для выполнения work:
template<typename T, size_t NumAxes = 3>
class vertex {
public:
template <typename U>
void setComp(size_t index, U value) { comp[index] = static_cast<T>(value); }
private:
T comp[NumAxes];
};
Теперь, если вы хотите, чтобы он был виртуальным, потому что вы хотите, чтобы подклассы могли с чем-то связываться (например, регистрировать каждое изменение значения), вам нужно определить не шаблонную функцию:
template<typename T, size_t NumAxes = 3>
class vertex {
public:
template <typename U>
void setComp(size_t index, U value)
{ _setComp(index, static_cast<T>(value)); }
protected:
T comp[NumAxes];
virtual void _setComp(size_t index, T value)
{ comp[index] = value; }
};
template<typename T, size_t NumAxes = 3>
class logged_vertex: public vertex<T, NumAxes> {
protected:
virtual void _setComp(size_t index, T value);
};
template<typename T, size_t NumAxes = 3>
void logged_vertex<T, NumAxes>::_setComp(size_t index, T value)
{ cout << "Index " << index << " changed from " << comp[index];
vertex<T, NumAxes>::_setComp(index, value);
cout << " to " << comp[index] << endl;
}
Это очень странное сочетание объектно-ориентированного программирования и общего программирования. Я думаю, тебе стоит выбрать одно или другое.
Сделайте класс вершины шаблоном или , определите базовый класс для параметра «значение» и получите классы обработчиков пользовательского типа.
Используйте полиморфизм вместо шаблонов.
Или ограничьте типы, которые вы хотите передавать, и сделайте перегрузки. И увеличить затраты на обслуживание.
Реализация этих решений предполагает использование boost::any или boost::variant для экономии времени.
Поскольку вершина может иметь произвольное число измерений
- почему бы не сделать ее
template<size_t N> class vector {
private:
boost::any elems[N];
}
тогда, чтобы избежать смешивания полиморфизма времени выполнения и полиморфизма времени компиляции через шаблоны? Или использовать перегрузки функций для любого возможного типа, если их число ограничено.
virtual void setComp(int, float) = 0;
virtual void setComp(int, bool) = 0;
Прежде всего, я бы спросил себя, действительно ли вам нужен полиморфный доступ к вершинным объектам во время выполнения. Например, если вам нужно иметь список объектов vertex* с различными типами (double, int и т.д.) и иметь к ним полиморфный доступ.
Мне кажется, что вершина - это типичный случай полиморфизма во время компиляции (т.е. template
template).