Застрял в этой проблеме некоторое время, и, похоже, не может найти никаких ответов!
Я хочу иметь базовый класс (рисунок) и несколько подклассов (круг, треугольник и т. Д.). Тогда я хочу, чтобы вектор содержал разные виды подклассов.
Дело в том, что все мои подклассы имеют размеры, но они описаны по-разному.
Кругу нужен только радиус, а треугольнику — база и высота, а квадрату — ширина и высота.
Это мой суперкласс
class Figure {
public:
//This function should take diffrent amount of values
virtual void setSize();
//More awesome stuff here
}
Это пример подклассов
class Circle {
public:
//This is a circle, only needs radius as size
void setSize( int _radius ) { radius = _radius; }
};
class Triangle {
public:
//This is a triangle, it needs both a base and height
void setSize( int _base, int _height ) { base = _base; height = _height; }
};
Так что теперь, если я вызываю getSize () из моего Figure * и он указывает на объект Circle, есть ли способ заставить мой суперкласс узнать его setSize (double) в классе Circle, который он должен вызвать?
Это так просто: если у ваших классов нет ничего общего, наследование не будет работать.
Что вы ожидаете случиться? Если я войду base->setSize(3)
для Triangle
какое поведение вы ожидаете?
Если вы можете работать с этим параметром, вам просто нужно переопределить функцию в вашем дочернем классе. Если вы хотите позвонить вашему более специализированному setSize(int, int)
Функция из этой переопределенной версии вы можете написать:
void setSize(int _radius) {
setSize(_radius, _radius);
}
Это, конечно, только пример, вы можете делать с параметрами все, что пожелаете, прежде чем передавать их в ваш более специализированный метод.
Предупреждение, предупреждение: если вы храните производные классы в векторе, вы нарезаете свои объекты. Помните, что STL использует копирование для перемещения членов данных. Так что если у вас есть vector<superclass>
и попытайтесь сохранить объект дочернего класса, STL скопирует часть суперкласса вашего объекта в свою собственную память и оставит вашу специализацию.
Чтобы обойти это, ваш первый инстинкт должен был бы использовать указатель на объект и сохранить этот указатель. Это откроет банку червей с утечками памяти, которые просто ожидают своего появления. Решение состоит в том, чтобы сохранить умный указатель из библиотеки Boost. Я предлагаю вам прочитать «За пределами стандартной библиотеки C ++ — введение в Boost» Бьорна Карлссона. Глава 1: smart_ptr
Как и в случае с Paranaix, у меня возникли трудности с представлением клиентов об использовании интерфейса дерева классов. В аналогичных реализациях типа «Figure» функции типа getSize () обычно возвращают ограничивающий прямоугольник. Суперкласс предоставляет виртуальную функцию Draw () для рисования фигуры внутри этой ограничительной рамки.
Как указывает Pananaix, идея с полиморфными функциями заключается в том, что функция представляет собой одну узко ограниченную идею, которая по-разному реализуется в производных классах. (это разделение интерфейса и принципа реализации)
В вашем проекте клиент должен знать тип объекта, чтобы вызвать / интерпретировать результат одной функции getSize (). (Для треугольника вы возвращаете / устанавливаете стороны, для круга — радиус). Это не тот путь.
Мой лучший совет — взглянуть на свой дизайн, попытаться разработать интерфейс и написать на его основе. Как только интерфейс заработает, напишите свои реализации.
Удачи.