Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.73
Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
#1

Наследование от 2Д или 3Д фигур - C++

24.10.2011, 20:58. Просмотров 1819. Ответов 19
Метки нет (Все метки)

Была задана задача: создать абстрактный класс Shape (фигура) с вычислением характеристики любой фигуры (площадь или объем) и выводом параметров. От него создать производные классы "2Д фигуры" и "3Д фигуры", также абстрактные. От класса "2Д фигуры" создать несколько производных классов - конкретных фигур. От класса "3Д фигуры", так же, создать несколько производных конкретных классов. Всё бы ничего, но вот я задумался над тем, что же будут наследовать конкретные фигуры из классов "2Д" и "3Д". Получается, что классы "2Д" и "3Д" должны содержать что-то свойственное всем двумерным и трехмерным соответственно. Мои рассуждения на этот счет: все 2Д фигуры родственны тем, что их можно изобразить на плоскости с помощью осей X и Y. Таким образом, я думаю, что можно сделать в "2Д" данные, содержащие выпуклость фигуры по осям X и Y. В "3Д" еще для оси Z. Рисовать фигуру не надо. Только посчитать площадь или объем. Может у кого мысли по-интереснее есть насчет классов "2Д" и "3Д"? Мне кажется сомнительным то что я надумал.
Прототипы:
Код
class Shape
{
protected:
	double SV; //площадь или объем
public:
	Shape();
	virtual ~Shape();
	virtual void print()=0;  //вывод параметров
	virtual void S_V()=0;  //рассчет площади или объема
};

class TwoD: public Shape
{
protected:
	double h,w;
public:
	TwoD(double H=0, double W=0);
	virtual ~TwoD()=0;
};

class ThreeD: public Shape
{
protected:
	double h,w,b;
public:
	ThreeD(double H=0, double W=0, double B=0);
	virtual ~ThreeD()=0;
};
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
hepr
61 / 33 / 5
Регистрация: 21.10.2010
Сообщений: 539
24.10.2011, 22:47     Наследование от 2Д или 3Д фигур #2
Предлагаю следующую иерархию:
Класс фигура:
члены: площадь и объем
виртуальные функции: вычислить площадь и объем
Класс 2D
массив 2D точек/прямых из которых состоит эта фигура(x,y)
Класс 3D
массив 3D точек/прямых из которых состоит эта фигура(x,y,z)
Далее например квадрат и правильный треугольник из 2D с переопределением всего что надо, тоже самое с кубом и тетраэдром из 3D
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
24.10.2011, 22:50     Наследование от 2Д или 3Д фигур #3
hepr, в вашей архитектуре у двухмерной фигуры может быть вычислен объем. Писать заглушку у всех фигур типа return 0.0; - не тру.
VadimTagil
14 / 14 / 1
Регистрация: 15.07.2011
Сообщений: 81
24.10.2011, 23:01     Наследование от 2Д или 3Д фигур #4
виртуальные функции: вычислить площадь и объем
виртуальная функция bool GetMetric(float* x,METRIC_TYPE m);
C++
1
2
res=shape.GetMetric(&s,METRIC_SURFACE);
res=shape.GetMetric(&v,METRIC_VOLUME);
функция устанавливает значение требуемой ыеличины в указанную переменную. Для двумерной фигуры попытка вычислить объем возвр. FALSE
hepr
61 / 33 / 5
Регистрация: 21.10.2010
Сообщений: 539
24.10.2011, 23:04     Наследование от 2Д или 3Д фигур #5
Цитата Сообщение от silent_1991 Посмотреть сообщение
hepr, в вашей архитектуре у двухмерной фигуры может быть вычислен объем.
Ну так, а кто сказал что я не предлагаю это сделать, виртуальные функции вычисление S и V я предлагаю ввести еще на уровне фигуры
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
24.10.2011, 23:07     Наследование от 2Д или 3Д фигур #6
Цитата Сообщение от hepr Посмотреть сообщение
Ну так, а кто сказал что я не предлагаю это сделать
Никто, я лишь сказал, что с моей точки зрения это неверно.
Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
24.10.2011, 23:11  [ТС]     Наследование от 2Д или 3Д фигур #7
Цитата Сообщение от hepr Посмотреть сообщение
Предлагаю следующую иерархию:
Класс фигура:
члены: площадь и объем
виртуальные функции: вычислить площадь и объем
Класс 2D
массив 2D точек/прямых из которых состоит эта фигура(x,y)
Класс 3D
массив 3D точек/прямых из которых состоит эта фигура(x,y,z)
Далее например квадрат и правильный треугольник из 2D с переопределением всего что надо, тоже самое с кубом и тетраэдром из 3D
Такс.. Тут просто в чем дело: классы Фигура, 2Д и 3Д являются абстрактными. Т.е. объектов их не будет. Создаются объекты уже по каким-то данным для конкретных классов. Данные будут вводиться такие как: длинна, высота или радиус. Если делать предложенную реализацию классов 2Д и 3Д, как я понимаю, это будет не только намного сложнее, но и абсолютно бесполезно для данной задачи. Хотя идея в общем ничего. Или я, всё же, чего-то тут не понимаю.
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
24.10.2011, 23:11     Наследование от 2Д или 3Д фигур #8

Не по теме:

Слабовато, товарищи форумчане. Покажите какую нибудь особую реализацию.


VadimTagil
14 / 14 / 1
Регистрация: 15.07.2011
Сообщений: 81
24.10.2011, 23:22     Наследование от 2Д или 3Д фигур #9
Цитата Сообщение от Riderik Посмотреть сообщение
это будет не только намного сложнее, но и абсолютно бесполезно для данной задачи
ну да, в принципе у абстрактных классов можно не делать никаких переменных, пусть они работают как интерфейсы. У каждой конткретной яигкры сделать переменные: длина, ширина, радиус и др., какие в конкретной фигуре нужны
Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
24.10.2011, 23:27  [ТС]     Наследование от 2Д или 3Д фигур #10
Цитата Сообщение от VadimTagil Посмотреть сообщение
ну да, в принципе у абстрактных классов можно не делать никаких переменных, пусть они работают как интерфейсы. У каждой конткретной яигкры сделать переменные: длина, ширина, радиус и др., какие в конкретной фигуре нужны
Получается что классы 2Д и 3Д для данной задачи бесполезны. Ведь интерфейс в классе Фигуры. Но всё же задание было именно с 2Д и 3Д. Есть вариант их оставить просто пустыми. Для виду чисто. Или использовать метод, как я предложил изначально: типа при создании класса "прямоугольник", можно просто в 2Д закидывать длину и ширину. И в новый класс ничего не добавлять. А при создании круга, можно в 2Д диаметр кинуть. Не очень так, но наверное лучше чем просто пустой класс?
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
24.10.2011, 23:31     Наследование от 2Д или 3Д фигур #11
Riderik, самый банальный вариант - свитч типов. Делаем класс Figure пустым, от него наследуем TwoDimFigure и ThreeDimFigure, в каждом из которых определяем свои методы (например, в 2д - площадь, в 3д - площадь поверхности и объём), а при обработке пробуем dynamic_cast'ом примести указатель на конкретную фигуру к 2д и к 3д. К какому типу получилось привести - те действия и выполняем.
Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
24.10.2011, 23:49  [ТС]     Наследование от 2Д или 3Д фигур #12
Цитата Сообщение от silent_1991 Посмотреть сообщение
Riderik, самый банальный вариант - свитч типов. Делаем класс Figure пустым, от него наследуем TwoDimFigure и ThreeDimFigure, в каждом из которых определяем свои методы (например, в 2д - площадь, в 3д - площадь поверхности и объём), а при обработке пробуем dynamic_cast'ом примести указатель на конкретную фигуру к 2д и к 3д. К какому типу получилось привести - те действия и выполняем.
ну, по-идее, в идеале так и должно быть. Но здесь дело другое: это первая лаба по наследованию и препод сказала, что площадь поверхностей не нужна. В общем тут нужно просто показать знание темы. Вот идея насчет пустого базового класса мне понравилась. Однако перечитав задание нашел следующую строчку: "реализовать абстрактный класс Shape содержащий интерфейс иерархий". Выходит, что именно он должен быть интерфейсом и пустым его оставить не получится. Да, задание странноватое :\
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
24.10.2011, 23:54     Наследование от 2Д или 3Д фигур #13
Riderik, тога будет беда, если мы попробуем объём вычислить у двухмерной фигуры... Может ввести метод name, который будет возвращать название фигуры? тогда его можно будет включить в базовый класс Фигура и переопределить в наследниках обоих подтипов фигур.

Добавлено через 1 минуту
Правда Фигура не будет содержать полный интерфейс, но общий (что и требуется от этого класса) содержать будет.
Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
24.10.2011, 23:56  [ТС]     Наследование от 2Д или 3Д фигур #14
Я сделал просто один метод с общим названием. В каждой фигуре он переопределен по-своему. Т.к. в 3Д не нужно считать площадь, а в 2Д не нужен объем, то одной функции, по-идее достаточно
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
24.10.2011, 23:57     Наследование от 2Д или 3Д фигур #15
Riderik, с точки зрения программирования да, но не с точки зрения проектирование (что более важно и чему, по идее, и следует обучиться в курсе).
Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
25.10.2011, 00:00  [ТС]     Наследование от 2Д или 3Д фигур #16

Не по теме:

Так у нас не проектирование. Это так, обучение программированию.


Итак если базовый класс - интерфейс, то получается, что 2Д и 3Д пустые? Или оставить так, как я надумал?
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
25.10.2011, 00:04     Наследование от 2Д или 3Д фигур #17
Riderik, при такой архитектуре (в данном случае) смысл классов 2д и 3д вообще теряется.
Mr.X
Эксперт С++
3039 / 1684 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
25.10.2011, 01:31     Наследование от 2Д или 3Д фигур #18
Цитата Сообщение от Riderik Посмотреть сообщение
Да, задание странноватое :\
Ну странное в вашем задании только то, что задано
Цитата Сообщение от Riderik Посмотреть сообщение
создать абстрактный класс Shape (фигура) с вычислением характеристики любой фигуры (площадь или объем)
т.е. абстрактному классу Shape велено вычислять то, чего он не знает.
Защищенные данные - это ошибка проектирования, в нормально спроектированных классах их не должно быть.
И не надо пихать данные в абстрактные классы, они не для этого предназначены.
Более корректная иерархия может так выглядеть:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
/////////////////////////////////////////////////////////////////////////////////////////
//Задача: создать абстрактный класс Shape (фигура) с вычислением характеристики 
//любой фигуры (площадь или объем) и выводом параметров. От него создать производные 
//классы "2Д фигуры" и "3Д фигуры", также абстрактные. От класса "2Д фигуры" создать 
//несколько производных классов - конкретных фигур. От класса "3Д фигуры", так же, 
//создать несколько производных конкретных классов.
/////////////////////////////////////////////////////////////////////////////////////////
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
/////////////////////////////////////////////////////////////////////////////////////////
class  T_figure
{
public:    
    virtual         ~T_figure()
    {}
    //-----------------------------------------------------------------------------------
    virtual void    print() = 0;
};
/////////////////////////////////////////////////////////////////////////////////////////
class  T_2D_figure : public T_figure
{
public:
    virtual         ~T_2D_figure()
    {}
    //-----------------------------------------------------------------------------------
    virtual void    print()
    {
        std::cout << "2D_figure"
                  << std::endl;
    }
    //-----------------------------------------------------------------------------------
    virtual double  get_area() = 0;
};
/////////////////////////////////////////////////////////////////////////////////////////
class  T_3D_figure : public T_figure
{
public:
    virtual         ~T_3D_figure()
    {}
    //-----------------------------------------------------------------------------------
    virtual void    print()
    {
        std::cout << "3D_figure"
                  << std::endl;
    }
    //-----------------------------------------------------------------------------------
    virtual double  get_volume() = 0;
};
/////////////////////////////////////////////////////////////////////////////////////////
class T_circle : public T_2D_figure
{
    double  radius_;
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    T_circle(double  radius = 0)
        : radius_(radius)
    {}
    //-----------------------------------------------------------------------------------
    virtual void    print()
    {
        T_2D_figure::print();
 
        std::cout << "circle:"
                  << std::endl
                  << "radius"
                  << '\t'
                  << "= "                  
                  << radius_
                  << ","
                  << std::endl
                  << "area"
                  << '\t'
                  << "= "                  
                  << get_area()
                  << "."
                  << std::endl
                  << std::endl;
    }
    //-----------------------------------------------------------------------------------
    virtual double  get_area()
    {
        return  radius_* radius_ * M_PI;
    }
};
/////////////////////////////////////////////////////////////////////////////////////////
class T_rectangle : public T_2D_figure
{
    double  width_;
    double  height_;
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    T_rectangle
        (
            double  width   = 0,
            double  height  = 0
        )
        :   
        width_      (width),
        height_     (height)
    {}
    //-----------------------------------------------------------------------------------
    virtual void    print()
    {
        T_2D_figure::print();
 
        std::cout << "rectangle:"
                  << std::endl
                  << "width"
                  << '\t'
                  << "= "                  
                  << width_
                  << ","
                  << std::endl
 
                  << "height"
                  << '\t'
                  << "= "                  
                  << height_
                  << ","
                  << std::endl
 
                  << "area"
                  << '\t'
                  << "= "                  
                  << get_area()
                  << "."
                  << std::endl
                  << std::endl;
    }
    //-----------------------------------------------------------------------------------
    virtual double  get_area()
    {
        return  width_ * height_;
    }
};
/////////////////////////////////////////////////////////////////////////////////////////
class T_sphere : public T_3D_figure
{
    double  radius_;
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    T_sphere(double  radius = 0)
        : radius_(radius)
    {}
    //-----------------------------------------------------------------------------------
    virtual void    print()
    {
        T_3D_figure::print();
        std::cout << "sphere:"
                  << std::endl
                  << "radius"
                  << '\t'
                  << "= "                  
                  << radius_
                  << ","
                  << std::endl
                  << "volume"
                  << '\t'
                  << "= "                  
                  << get_volume()
                  << "."
                  << std::endl
                  << std::endl;
    }
    //-----------------------------------------------------------------------------------
    virtual double  get_volume()
    {
        return  radius_ * radius_* radius_ * M_PI * 4.0 / 3.0;
    }
};
/////////////////////////////////////////////////////////////////////////////////////////
class T_parallelepiped : public T_3D_figure
{
    double  length_;
    double  width_;
    double  height_;
    //-----------------------------------------------------------------------------------
public:
    //-----------------------------------------------------------------------------------
    T_parallelepiped
        (
            double  length  = 0,
            double  width   = 0,
            double  height  = 0
        )
        :   
        length_     (length),
        width_      (width),
        height_     (height)
    {}
    //-----------------------------------------------------------------------------------
    virtual void    print()
    {
        T_3D_figure::print();
        std::cout << "parallelepiped:"
                  << std::endl
 
                  << "length"
                  << '\t'
                  << "= "                  
                  << length_
                  << ","
                  << std::endl
 
                  << "width"
                  << '\t'
                  << "= "                  
                  << width_
                  << ","
                  << std::endl
 
                  << "height"
                  << '\t'
                  << "= "                  
                  << height_
                  << ","
                  << std::endl
 
                  << "volume"
                  << '\t'
                  << "= "                  
                  << get_volume()
                  << "."
                  << std::endl
                  << std::endl;
    }
    //-----------------------------------------------------------------------------------
    virtual double  get_volume()
    {
        return  length_ * width_* height_;
    }
};
/////////////////////////////////////////////////////////////////////////////////////////
int main()
{
    T_circle            circle(1);
    circle.print();
 
    T_rectangle         rectangle(2, 3);
    rectangle.print();
 
    T_sphere            sphere(1);
    sphere.print();
 
    T_parallelepiped    parallelepiped(2, 3, 4);
    parallelepiped.print();
}
Riderik
28 / 28 / 1
Регистрация: 24.07.2011
Сообщений: 171
26.10.2011, 00:40  [ТС]     Наследование от 2Д или 3Д фигур #19
Сегодня уточнил задание. Препод требует следующее:
Абстрактный класс Shape содержит виртуальные методы вычисления площади и объема (две функции). Также метод вывода информации. Т.е. этот класс обязательно должен быть интерфейсом. Далее абстрактный класс 2Д имеет в себе данные о координатах базовой точки 2Д фигуры. И реализован метод вычисления объема: пустая реализация (либо вывод ошибки). Далее в конкретных 2Д фигурах добавлены координаты других необходимых точек и реализованы методы вычисления площади и вывода информации. В 3Д аналогично, но с вычислением площади поверхности.

Защищенные данные - это ошибка проектирования, в нормально спроектированных классах их не должно быть.
Об этом вообще впервые слышит.

Задание довольно простое. Но насколько... корректно, что ли?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.10.2011, 01:02     Наследование от 2Д или 3Д фигур
Еще ссылки по теме:

C++ Структура программы или наследование, без использования конструктора базового класса
C++ Множественное наследование графических фигур
C++ Определить какая из фигур – круг или квадрат - имеет большую площадь
Наследование.Геометрические фигуры.Коллекция геометрических фигур.Непонятна работа с массивом C++
Штриховка фигур C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
silent_1991
Эксперт С++
4952 / 3028 / 149
Регистрация: 11.11.2009
Сообщений: 7,026
Завершенные тесты: 1
26.10.2011, 01:02     Наследование от 2Д или 3Д фигур #20
Цитата Сообщение от Riderik Посмотреть сообщение
Об этом вообще впервые слышит.
Судя по той "архитектуре", которую он требует, это совершенно неудивительно.

Цитата Сообщение от Riderik Посмотреть сообщение
Но насколько... корректно, что ли?
См. выше.
Yandex
Объявления
26.10.2011, 01:02     Наследование от 2Д или 3Д фигур
Ответ Создать тему
Опции темы

Текущее время: 20:32. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru