Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
36 / 23 / 10
Регистрация: 14.11.2013
Сообщений: 85

Не могу организовать иерархию классов

17.11.2013, 11:41. Показов 1565. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет!
Нужен совет как правильно сделать наследование.
Чтобы через указатель базового класса (Форма) можно было бы создать объект производного класса (Точка).
А так же чтобы можно было вызывать методы из производного.

Shapes.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
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
Shapes.h:
 
#ifndef SHAPES_H
#define SHAPES_H
#include <iostream>
 
 
class Shape
{
public:
    virtual ~Shape() {};
 
    virtual void PrintShapeName() const = 0;
    virtual void Print() const = 0;
    virtual double GetArea() const      { return 0.0; };
    virtual double GetVolume() const    { return 0.0; };
};
 
 
class Point : public Shape
{
private:
    double      m_x;
    double      m_y;
 
public:
    Point(double x=0.0,  double y=0.0);
    ~Point();
 
    void SetX(double x);
    void SetY(double y);
    void SetPoint(double x,  double y);
 
    double GetX() const;
    double GetY() const;
 
    virtual void PrintShapeName() const override;
    virtual void Print() const override;
};
 
 
class Circle : public Point
{
private:
    double      m_radius;
 
public:
    Circle(double x=0.0,  double y=0.0,  double radius=1.0);
    ~Circle();
 
    void SetRadius(double radius);
    double GetRadius() const;
};
 
#endif // SHAPES_H





main.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <stdlib.h>
#include "include/Shapes.h"
 
 
int main()
{
    Shape   *shape;
 
    shape = new Point;
    shape->SetPoint(1.0, 1.0);  // Невозможно указать координаты точки! Этого метода нет в класса Shape
 
    system("pause");
    return 0;
}
Можно SetPoint() перенести в базовый, но мне не нравится эта идея. Каждый раз при добавлении нового класса придется вносить изменения в базовый

Дайте совет что делать
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
17.11.2013, 11:41
Ответы с готовыми решениями:

Разработать иерархию классов, демонстрирующее работу с коллекцией объектов разных классов
Задание: Разработать в соответствии с индивидуальным заданием иерархию классов и приложение, демонстрирующее работу с коллекцией объектов...

Организовать иерархию классов
В общем, ситуация такая: пишется что-то наподобие простенького движка для шариков, которые будут бегать по полю. Управление шариками...

Организовать иерархию классов
Организовать иерархию классов, в которых предусмотреть закрытые поля с соответствующими свойствами, а также написать программный код двух...

15
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
17.11.2013, 12:21
Цитата Сообщение от LuxArt Посмотреть сообщение
Дайте совет что делать
Если просто надо по указателю на базовый класс вызывать методы дочернего, то надо приводить типы:
C++
1
2
3
4
5
Point* p = dynamic_cast<Point*>(shape);
if( p ) // shape является Point
{
   p->SetPoint();
}
1
36 / 23 / 10
Регистрация: 14.11.2013
Сообщений: 85
17.11.2013, 17:01  [ТС]
Цитата Сообщение от Tulosba Посмотреть сообщение
надо приводить типы:
Можно ли это сделать без приведения типов? Чтобы через указатель базового класса вызвать функцию из производного?
Понятно, что базовые классы ничего не знают о производных, но все таки

Как-нибудь так
C++
1
2
3
    Shape   *shape = new Point;
 
    (Point *)shape->SetPoint(1.1, 2.2);
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
17.11.2013, 17:06
Цитата Сообщение от LuxArt Посмотреть сообщение
C++
1
(Point *)shape->SetPoint(1.1, 2.2);
Видимо имелось в виду:
C++
1
((Point *)shape)->SetPoint(1.1, 2.2);
Но это ведь тоже приведение типа, только в Си-стиле.
1
36 / 23 / 10
Регистрация: 14.11.2013
Сообщений: 85
17.11.2013, 17:39  [ТС]
Цитата Сообщение от Tulosba Посмотреть сообщение
((Point *)shape)->SetPoint(1.1, 2.2);
Спасибо все работает

C++
1
2
3
4
5
    Shape   *shape = new Point;
 
    ((Point *)shape)->SetPoint(1.1, 2.2);
 
    ((Point *)shape)->Print();
Добавлено через 2 минуты
Оказывается ничего сложного нет. Только скобки были неправильно расставлены. Из-за этого и не компилировалась программа

Добавлено через 16 минут
Еще один вопрос есть.
Смотрите. Каждый раз при выборе любой функции из производного класса, этот указатель приходится приводить к правильному типу, нужно всякий раз указывать (Circle *):

C++
1
2
3
4
5
6
7
    Shape   *shape = new Circle;
 
    ((Circle *)shape)->SetPoint(1.1, 2.2);
    ((Circle *)shape)->SetRadius(10.0);
 
    std::cout << "x = " << ((Circle *)shape)->GetX() << ", y = " << ((Circle *)shape)->GetY() << std::endl;
    std::cout << "Площадь = " << ((Circle *)shape)->GetArea() << std::endl;
Можно от этого избавиться?
0
All rights reserved.
93 / 83 / 24
Регистрация: 03.08.2013
Сообщений: 258
17.11.2013, 17:44
А можно такой вопрос задать, зачем вам возится с базовым классом? Наплодили его потомков вот и пользуйтесь их услугами напрямую через их объекты)
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
17.11.2013, 17:47
Цитата Сообщение от LuxArt Посмотреть сообщение
Можно от этого избавиться?
Вводим дополнительную переменную:
C++
1
2
3
Circle* circle = (Circle *)shape;
circle->SetPoint(1.1, 2.2);
cirlce->SetRadius(10.0);
но лучше использовать dynamic_cast
0
36 / 23 / 10
Регистрация: 14.11.2013
Сообщений: 85
17.11.2013, 17:55  [ТС]
StackOverflow, Хочу создать массив объектов базового класса. Точнее указателей на базовый класс.
И потом динамически выделить для них память, т.е. создать производные объекты (точка, круг, ...)
Потом обращаться к нужным функциям только через указатель на базовый класс

А сейчас тренируюсь с этими классами. Пробую как лучше все организовать

Добавлено через 6 минут
Цитата Сообщение от Tulosba Посмотреть сообщение
Вводим дополнительную переменную:
Хотелось бы без дополнительной переменной)

ладно, пожалуй пока хватит. Думаю по другому никак не получится. Нужно всегда приводить указатель
0
17.11.2013, 18:00

Не по теме:

Может стоит задаться вопросом стоит ли тут использовать наследование ?

0
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
17.11.2013, 18:04
LuxArt Дайте определение массив и поймете, что Ваша идея не совсем коректна.
0
36 / 23 / 10
Регистрация: 14.11.2013
Сообщений: 85
17.11.2013, 18:12  [ТС]
Цитата Сообщение от Avazart Посмотреть сообщение
Может стоит задаться вопросом стоит ли тут использовать наследование ?
У меня такая одна интересная идея есть. Есть указатель на базовый класс (Форма). Через этот указатель я могу создать круг, квадрат, цилиндр. Да и вообще все что пожелаю. И для этого нужен только один указатель! Другие переменные даже не нужны. Таким способом я могу создать один объект.
А если нужно несколько объектов, то для этого подойдет массив указателей на базовый класс

Добавлено через 1 минуту
Цитата Сообщение от stima Посмотреть сообщение
LuxArt Дайте определение массив и поймете, что Ваша идея не совсем коректна.
Корректна. Каждый элемент в массиве - это указатель. А на что он указывает это уже другой вопрос)
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
17.11.2013, 18:18
Цитата Сообщение от LuxArt Посмотреть сообщение
У меня такая одна интересная идея есть.
Почитай по фабрики

http://ru.wikipedia.org/wiki/%... 8%D1%8F%29
1
503 / 352 / 94
Регистрация: 22.03.2011
Сообщений: 1,112
17.11.2013, 18:28
Цитата Сообщение от LuxArt Посмотреть сообщение
Корректна. Каждый элемент в массиве - это указатель. А на что он указывает это уже другой вопрос)
В конрне не верно. Массив это набор ОДИНОТИПНЫХ элементов. А то что он реализуется через указатели это уже совсем другое.

Так что если у Вас массив элементов баззового класса, а Вы в процессе прохода по массиву, хотите от них вызовов дочерних методов и эти методы не вписываются в баззовый класс (через virtual), то стоит подумать, чтобы добавить еще один(или несколько) массивов, которые будут хранить ОДНОТИПНЫЕ элементы.
1
 Аватар для агерон
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
17.11.2013, 19:04
Вы не понимаете основ ООП, что такое базовый класс, через указатель базового класса вы НИКОГДА не вызовете тех функций классов потомков которые не определены как виртуальные в классе предке т. е.
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
class CBase
{
    public:
        virtual int GetBaseProperty();
        virtual void SetBaseProperty(int value);
}
 
class CExtended:public CBase
{
    public:
        virtual int GetBaseProperty() overidde;
        virtual void SetBaseProperty(int value) overidde;
        virtual int GetExtendedProperty() overidde;
        virtual void SetExtendedProperty(int value) overidde;               
} 
 
void main()
{
    CExtended *extended = new CExtended();
    CBase *base = extended;
    extended -> SetBaseProperty(5); //так можно     
    extended -> SetExtendedProperty(5); //и так можно 
    base->SetBaseProperty(5);// и так можно, т к класс СBase "знает" про SetBaseProperty, мы вызовем extended -> SetBaseProperty основываясь на VMT
    base->SetExtendedProperty(5) // а вот так нельзя т. к. класс CBase ничего "не знает" про SetExtendedProperty и это вызовет ошибку компиляции  
}
Добавлено через 1 минуту
Avazart, про фабрики ему читать пока рано пусть сперва выучит основы ООП
0
36 / 23 / 10
Регистрация: 14.11.2013
Сообщений: 85
17.11.2013, 21:30  [ТС]
Цитата Сообщение от агерон Посмотреть сообщение
Avazart, про фабрики ему читать пока рано пусть сперва выучит основы ООП
Почему это рано? Очень даже интересно почитать.
А основы ООП я итак знаю.
Даже если я и ошибся и чего-то недопонимаю, то ничего страшного
0
 Аватар для агерон
447 / 300 / 65
Регистрация: 12.10.2009
Сообщений: 1,162
17.11.2013, 22:48
Проблема в том что Фабрика это шаблон проектирования которые желательно читать после осознания ООП, я вам не запрещаю читать про паттерны, упаси боже, просто не факт что все прочитанное вы сможете корректно принять, в связи с непониманием что такое паттерны и когда их уместно применять

Добавлено через 1 минуту
Данные выводы об вашем уровне осознания ООП следуют из вашего непонимания как нужно работать с классами
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
17.11.2013, 22:48
Помогаю со студенческими работами здесь

Организовать иерархию классов: дом, улица, город
Обязательно реализовать в каждом классе метод ToString, который будет форматировать вывод информации об объекте в виде строке. Если у...

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

Не могу понять иерархию классов java
Я не могу понять что есть что. Вот к примеру, есть пакет java.util.collection и следующая схема Все стрелочки идут к какому-то одному...

Создать иерархию классов
создать иерархию класса Animal &gt;Cat &gt;Siamskaya Persidskai и определить , общие методы и уникальные методы для каждого класса, Не могу...

Построить иерархию классов
Задание: 1)Создать абстрактный класс Trans с методами позволяющим вывести на экран информацию о транспортном средстве, а также...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru