Суперкласс и подкласс, вызовы различных функций в зависимости от подкласса

Застрял в этой проблеме некоторое время, и, похоже, не может найти никаких ответов!

Я хочу иметь базовый класс (рисунок) и несколько подклассов (круг, треугольник и т. Д.). Тогда я хочу, чтобы вектор содержал разные виды подклассов.

Дело в том, что все мои подклассы имеют размеры, но они описаны по-разному.

Кругу нужен только радиус, а треугольнику — база и высота, а квадрату — ширина и высота.

Это мой суперкласс

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, который он должен вызвать?

1

Решение

Это так просто: если у ваших классов нет ничего общего, наследование не будет работать.
Что вы ожидаете случиться? Если я войду base->setSize(3) для Triangle какое поведение вы ожидаете?

Если вы можете работать с этим параметром, вам просто нужно переопределить функцию в вашем дочернем классе. Если вы хотите позвонить вашему более специализированному setSize(int, int) Функция из этой переопределенной версии вы можете написать:

void setSize(int _radius) {
setSize(_radius, _radius);
}

Это, конечно, только пример, вы можете делать с параметрами все, что пожелаете, прежде чем передавать их в ваш более специализированный метод.

2

Другие решения

Предупреждение, предупреждение: если вы храните производные классы в векторе, вы нарезаете свои объекты. Помните, что STL использует копирование для перемещения членов данных. Так что если у вас есть vector<superclass> и попытайтесь сохранить объект дочернего класса, STL скопирует часть суперкласса вашего объекта в свою собственную память и оставит вашу специализацию.

Чтобы обойти это, ваш первый инстинкт должен был бы использовать указатель на объект и сохранить этот указатель. Это откроет банку червей с утечками памяти, которые просто ожидают своего появления. Решение состоит в том, чтобы сохранить умный указатель из библиотеки Boost. Я предлагаю вам прочитать «За пределами стандартной библиотеки C ++ — введение в Boost» Бьорна Карлссона. Глава 1: smart_ptr

Как и в случае с Paranaix, у меня возникли трудности с представлением клиентов об использовании интерфейса дерева классов. В аналогичных реализациях типа «Figure» функции типа getSize () обычно возвращают ограничивающий прямоугольник. Суперкласс предоставляет виртуальную функцию Draw () для рисования фигуры внутри этой ограничительной рамки.

Как указывает Pananaix, идея с полиморфными функциями заключается в том, что функция представляет собой одну узко ограниченную идею, которая по-разному реализуется в производных классах. (это разделение интерфейса и принципа реализации)

В вашем проекте клиент должен знать тип объекта, чтобы вызвать / интерпретировать результат одной функции getSize (). (Для треугольника вы возвращаете / устанавливаете стороны, для круга — радиус). Это не тот путь.

Мой лучший совет — взглянуть на свой дизайн, попытаться разработать интерфейс и написать на его основе. Как только интерфейс заработает, напишите свои реализации.

Удачи.

0

По вопросам рекламы [email protected]