Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
Shiningemerald
 Аватар для Electroflower
384 / 117 / 22
Регистрация: 05.01.2012
Сообщений: 951

Коллекция объектов базового класса

21.04.2021, 11:54. Показов 1590. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго дня!

У меня есть несколько классов одинаковых по предметной области(это фигуры круги и треугольники), просто рисуются они по разному и пришлось засунунть их в разные классы.
Вот эти простые классы:
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
//треугольник
class Treangle
{
        int x; //координата х
        int y; //координата y
        TColor color; //цвет фигуры
        int size; //0.5 стороны треугольника
        AnsiString text; //текст внутри фигуры
public:
        Treangle(){}
        Treangle(int xNew, int yNew, TColor colorNew, int sizeNew, AnsiString textNew)
                {x = xNew; y = yNew; color = colorNew; size = sizeNew; text = textNew;}
        void draw(TCanvas* Canvas);
};
 
//простой круг
class EllipseSimple
{
        int x; //координата х
        int y; //координата y
        TColor color; //цвет фигуры
        int radius; //радиус окружности
        AnsiString text; //текст внутри фигуры
public:
        EllipseSimple(){}
        EllipseSimple(int xNew, int yNew, TColor colorNew, int radiusNew, AnsiString textNew)
                {x =  xNew; y = yNew; color = colorNew; radius = radiusNew; text = textNew;}
        void draw(TCanvas* Canvas);
};
 
//круг с крестом
class EllipseCross
{
        int x; //координата х
        int y; //координата y
        TColor color; //цвет фигуры
        int radius; //радиус окружности
public:
        EllipseCross(){}
        EllipseCross(int xNew, int yNew, TColor colorNew, int radiusNew)
                {x =  xNew; y = yNew; color = colorNew; radius = radiusNew;}
        void draw(TCanvas* Canvas);
        int round (double value);
};
 
//круг с линиями сбоку
class EllipseBordered
{
        int x; //координата х
        int y; //координата y
        TColor color; //цвет фигуры
        int radius; //радиус окружности
        AnsiString text; //текст внутри фигуры
        TColor borderColor; //цвет бортов
public:
        EllipseBordered(){}
        EllipseBordered(int xNew, int yNew, TColor colorNew, int radiusNew, AnsiString textNew, TColor borderColorNew)
                {x =  xNew; y = yNew; color = colorNew; radius = radiusNew; text = textNew; borderColor = borderColorNew;}
        void draw(TCanvas* Canvas);
        int round (double value);
};

В свою очередь есть другой класс, которые должен хранить коллекцию фигур. И тут приходит мысль что засунуть объекты классов фигур в одну коллекцию нельзя... Тогда появляется идея создать некий базовый класс, от которого будут наследоваться классы фигур.
Вопрос, поможет ли это и как это организовать? Как потом объявлять объекты классов?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.04.2021, 11:54
Ответы с готовыми решениями:

Как создать динамический массив объектов базового класса и заполнить его наследниками базового класса?
#include <iostream> using namespace std; class P { int p; public: P() {

Заполнить массив объектов базового класса
Суть задачи: есть базовый класс Участник и производные от него Студент и Школьник. Нужно заполнить массив объектов базового класса. ...

Создание базового класса. Наследование от базового класса
видало 2 ошибку 1) Ошибка LNK1120 неразрешенных внешних элементов: 1 2) Ошибка LNK2019 ссылка на неразрешенный внешний символ _main...

16
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
21.04.2021, 12:05
Цитата Сообщение от Electroflower Посмотреть сообщение
Вопрос, поможет ли это и как это организовать? Как потом объявлять объекты классов?
Можно.
Хранить по указателю на базовый класс. Метод draw должен быть виртуальным.

Собственно учебничек любой открываете на главе про полиморфизм и там будет какой-то такой пример.
2
фрилансер
 Аватар для Алексей1153
6455 / 5657 / 1129
Регистрация: 11.10.2019
Сообщений: 15,073
21.04.2021, 12:27
Electroflower, например, так

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
#include <vector>
#include <memory>
#include <iostream>
 
class TCanvas;
 
class CFigure
{
protected:
    int x{}; //координата х
    int y{}; //координата y
    int color{}; //цвет фигуры
public:
    virtual void draw(TCanvas* Canvas)const=0;
    virtual ~CFigure()=default;
};
 
class Triangle:public CFigure
{
    int size{};
public:
    void draw(TCanvas* Canvas)const override
    {
        std::cout<<"painting: Triangle"<<'\n';
    }
};
 
class EllipseSimple:public CFigure
{
    int radius{};
public:
    void draw(TCanvas* Canvas)const override
    {
        std::cout<<"painting: EllipseSimple"<<'\n';
    }
};
 
class EllipseCross:public CFigure
{
    int radius; //радиус окружности
public:
    void draw(TCanvas* Canvas)const override
    {
        std::cout<<"painting: EllipseCross"<<'\n';
    }
};
 
class EllipseBordered:public CFigure
{
    int radius; //радиус окружности
public:
    void draw(TCanvas* Canvas)const override
    {
        std::cout<<"painting: EllipseBordered"<<'\n';
    }
};
 
struct CCollection
{
    std::vector<std::unique_ptr<CFigure>> m_list;
    
    void PaintAll()const
    {
        for(auto& f:m_list)
        {
            f->draw(nullptr);
        }
    }
};
 
int main()
{
    CCollection collection;
    
    collection.m_list.emplace_back(std::make_unique<Triangle>(/*аргументы для конструктора*/));
    collection.m_list.emplace_back(std::make_unique<EllipseSimple>(/*аргументы для конструктора*/));
    collection.m_list.emplace_back(std::make_unique<EllipseCross>(/*аргументы для конструктора*/));
    collection.m_list.emplace_back(std::make_unique<EllipseBordered>(/*аргументы для конструктора*/));
    
    collection.PaintAll();
    
}
1
365 / 321 / 219
Регистрация: 21.02.2013
Сообщений: 756
21.04.2021, 12:31
если правильно понял задание, то через указатель на базовый класс можно все фигуры в одну коллекцию собрать
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
#include <iostream>
#include <vector>
using namespace std;
class Shape{
 
public:
 
    virtual void print() = 0;
};
 
 
class Triangle: public Shape{
 
public:
 
    void print(){
 
       cout << "Triangle" << endl;
    }
};
 
 
class Rectangle: public Shape{
 
public:
 
    void print(){
 
       cout << "Rectangle" << endl;
    }
};
 
int main()
{
    vector<Shape*> vec;// тут указатель на базовый класс
 
    vec.push_back(new Rectangle());
    vec.push_back(new Triangle());
    vec.push_back(new Rectangle());
 
    vec[0]->print();
    vec[1]->print();
    vec[2]->print();
    return 0;
}
1
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
21.04.2021, 16:36
jurok_85, а кто за Вас будет удалять ети new-ы ? ))
Вектор указатели не будет трогать. Они ему даром не нужны.
0
Shiningemerald
 Аватар для Electroflower
384 / 117 / 22
Регистрация: 05.01.2012
Сообщений: 951
22.04.2021, 10:55  [ТС]
Алексей1153, ваш пример почему-то не работает.
на виртуальный деструктор базового класса ругается..
C++
1
virtual ~CFigure()=default;
0
фрилансер
 Аватар для Алексей1153
6455 / 5657 / 1129
Регистрация: 11.10.2019
Сообщений: 15,073
22.04.2021, 10:58
Electroflower, как именно ругается? Какие ругательства пишет?

https://onlinegdb.com/SkNihjA8u
1
Shiningemerald
 Аватар для Electroflower
384 / 117 / 22
Регистрация: 05.01.2012
Сообщений: 951
22.04.2021, 11:15  [ТС]
Алексей1153, E2088 Bad syntax for pure function definition
0
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
22.04.2021, 11:50
Electroflower, С++11 или выше должен быть доступен для того, чтобы использовать такой код. Какой у вас компилятор?
1
Shiningemerald
 Аватар для Electroflower
384 / 117 / 22
Регистрация: 05.01.2012
Сообщений: 951
22.04.2021, 17:27  [ТС]
DrOffset, С++ builder 6....
0
Shiningemerald
 Аватар для Electroflower
384 / 117 / 22
Регистрация: 05.01.2012
Сообщений: 951
23.04.2021, 15:45  [ТС]
Алексей1153, я делаю вот так вот на примере двух классов:

Классы:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class CFigure
{
    int x; //координата х
    int y; //координата y
    TColor color; //цвет фигуры
public:
    virtual void draw(TCanvas* Canvas);
};
 
//треугольник
class Treangle : public CFigure
{
        //int x; //координата х
        //int y; //координата y
        //TColor color; //цвет фигуры
        int size; //0.5 стороны треугольника
        AnsiString text; //текст внутри фигуры
public:
        Treangle(){}
        Treangle(int xNew, int yNew, TColor colorNew, int sizeNew, AnsiString textNew)
                {x = xNew; y = yNew; color = colorNew; size = sizeNew; text = textNew;}
        void draw(TCanvas* Canvas);
};
Вызов пока без вектора:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int xCenter=60;
int yCenter=60;
int radius=10;
int halfLine = 20;
 
CFigure *ptr;
Treangle kek(xCenter, yCenter, clGreen, halfLine, "22");
ptr = &kek;
ptr.draw(Canvas);
 
}
Это сделано по примеру и по логике должен вызываться draw нужного класса...но ругается на строчку
C++
1
ptr.draw(Canvas);
0
фрилансер
 Аватар для Алексей1153
6455 / 5657 / 1129
Регистрация: 11.10.2019
Сообщений: 15,073
23.04.2021, 16:10
Цитата Сообщение от Electroflower Посмотреть сообщение
class CFigure
{
public:
virtual void draw(TCanvas* Canvas);

virtual ~CFigure(){};//нужно добавить виртуальный деструктор
};
либо сделай функцию чистой:
virtual void draw(TCanvas* Canvas)=0;

либо с пустым телом:
virtual void draw(TCanvas* Canvas){}

В классах-наследниках слово virtual можно не писать, а вот слово override - лучше завести привычку дописывать для виртуальных функций. Ну тело функции должно быть (если хочется создавать объект класса)

C++
1
2
3
4
5
   ...
   void draw(TCanvas* Canvas)override
   {
   }
   ...
добавил - также в родительском классе сделай виртуальный деструктор. На всякий случай
1
Shiningemerald
 Аватар для Electroflower
384 / 117 / 22
Регистрация: 05.01.2012
Сообщений: 951
23.04.2021, 16:23  [ТС]
Алексей1153,
ф-я draw в базе у меня написана с пустым телом.

у меня всегда вызов идет базовой ф-ии draw, вот в чем странность.

override у меня ошибку выдает.

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int xCenter=60;
int yCenter=60;
int radius=10;
int halfLine = 20;
 
std::vector<CFigure> figureVector;
Treangle kek(xCenter, yCenter, clGreen, halfLine, "22");
figureVector.push_back(kek);
int count=0;
for(int i =0; i<figureVector.size(); i++)
        {
         figureVector[i].draw(Canvas);
        }
}
Добавлено через 45 секунд
Может через указатели надо как -то?
0
фрилансер
 Аватар для Алексей1153
6455 / 5657 / 1129
Регистрация: 11.10.2019
Сообщений: 15,073
23.04.2021, 17:49
Цитата Сообщение от Electroflower Посмотреть сообщение
override у меня ошибку выдает.
стандарт староват, значит. Тогда не пиши его (override то есть)

Цитата Сообщение от Electroflower Посмотреть сообщение
std::vector<CFigure> figureVector;
нужен вектор указателей на CFigure, а не самих объектов CFigure

Добавлено через 31 секунду
ну и объекты создавать динамически
1
Shiningemerald
 Аватар для Electroflower
384 / 117 / 22
Регистрация: 05.01.2012
Сообщений: 951
26.04.2021, 09:36  [ТС]
Алексей1153, все равно что-то не так... не могу понять что. Почему-то все еще вызывается метод родительского класса...

Unit1.h :
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
class CFigure
{
public:
    int x; //координата х
    int y; //координата y
    TColor color; //цвет фигуры
    virtual ~CFigure(){}
    virtual void draw(TCanvas* Canvas)=0;
};
 
//треугольник
class Treangle : public CFigure
{
        //int x; //координата х
        //int y; //координата y
        //TColor color; //цвет фигуры
        int size; //0.5 стороны треугольника
        AnsiString text; //текст внутри фигуры
public:
        Treangle(){}
        Treangle(int xNew, int yNew, TColor colorNew, int sizeNew, AnsiString textNew)
                {x = xNew; y = yNew; color = colorNew; size = sizeNew; text = textNew;}
        virtual void draw(TCanvas* Canvas);
};
Unit1.cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int xCenter=60;
int yCenter=60;
int radius=10;
int halfLine = 20;
 
std::vector<CFigure*> figureVector;
Treangle tr(xCenter, yCenter, clGreen, halfLine, "22");
//figureVector.push_back(tr);
CFigure *ptr;
ptr = &tr;
figureVector.push_back(ptr);
 
for(int i =0; i<figureVector.size(); i++)
        {
        figureVector[i].draw(Canvas);
        }
}
Добавлено через 17 минут
Видимо стоило почитать про разницу между точкой и стрелкой...
0
фрилансер
 Аватар для Алексей1153
6455 / 5657 / 1129
Регистрация: 11.10.2019
Сообщений: 15,073
26.04.2021, 09:52
Цитата Сообщение от Electroflower Посмотреть сообщение
figureVector[i].draw
в векторе лежат указатели, а не объекты

кроме того,
Цитата Сообщение от Алексей1153 Посмотреть сообщение
ну и объекты создавать динамически
а они у тебя создаются на стеке

вот тут посмотри
https://onlinegdb.com/BJ8VmyVw_
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9007 / 4708 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
26.04.2021, 11:21
Electroflower, приветствую)
Я бы (если только ваши фигуры - только графика, а не клиентская область для отлова и обработки событий ака контролл) создал базовый класс типа Shape с виртуальным методом void Draw() и , например, контейнером указателей на себя. Это могут быть смарт пойнтеры, тоже.
В этом случае вы сможете создавать эллипс с полосатой границей как пару вложенных эллипсов, а крест запихнуть (как вы говорите) куда пожелаете. Даже в треугольник. И отрисовка может состоять в отрисовке родителя и последующей отрисовке всего содержимого его контейнера)
Я бы предпочёл вектор shared_ptr<Shape> наверное. Но если это задание - сделать и забыть, - не заморачивайтесь)
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
26.04.2021, 11:21
Помогаю со студенческими работами здесь

Вызов метода производного класса через обращение к методу базового класса
Добрый день. Изучаю основы ООП, наткнулся на проблему. Если создавать классы внутри main.cpp, то всё нормально. Если же создавать в...

Почему объект производного класса не видит префиксный оператор из базового класса?
Короче создал я базовый класс с перегруженным префиксным оператором ++. Потом чтоб его затюнинговать, сделал ему производный класс с...

Как сложить объект базового класса с объектом производного(наследуемого класса)
Как умножить объект базового класса с объектом производного(наследуемого класса): ozenka - объект базового класса, а ves- производного ...

Создать объект производного класса с передачей параметров в конструктор базового класса
Доброго времени суток! Если не затруднит, утолите мой интерес, пожалуйста! Есть базовый и производный классы с атрибутами a, b - у...

Вызвать конструктор производного класса без конструктора базового класса
Здравствуйте! У меня есть базовый класс треугольник и производный класс равносторонний треугольник.В конструкторе треугольника вводятся...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru