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

создать метод доступа к функциям класса-наследника

23.10.2011, 14:42. Показов 1462. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Допустим, есть базовый класс Фигура и наследники "Треугольник", "Квадрат". Мне нужно создать метод доступа к функциям наследника.
Просьба не говорить: "это не правильный подход к ООП, юзай абстрактный метод". Мне нужна именна такая реализация (Агрегирование)

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Figure
{
public:
    // создать метод доступа ToTriangle(), ToRectangle()
};
struct Triangle // : Figure
{
    int GetArea() const { return itsArea; }
};
struct Rectangle // : Figure
{
    int GetPerimeter() const { return itsPerimeter; }
};
 
void main()
{ 
    Figure pFigure;
    /*     вот тут должен открываться доступ к функциям Triangle.*/
    pFigure.ToTriangle().GetArea();
    /*     вот тут должен открываться доступ к функциям Rectangle.*/
    pFigure.ToPerimter().GetPerimter();
}
Пытался сам реализовать с приведениями типов. Покажите свою версию реализаций доступа(без ссылок на сторонние ресурсы)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.10.2011, 14:42
Ответы с готовыми решениями:

Проблема доступа к функциям-членам одного класса из другого
Есть два класса, A и B: class B { }; class A { private:

Вызвать метод базового класса из метода наследника
Есть базовый класс с виртуальным методом, выводящим значение его полей. В классе-наследнике есть метод с таким же названием, и он также...

Дружественный метод класса и ошибка доступа
class B; class A { public: void f(B& b); }; class B { private:

11
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
23.10.2011, 15:08
Правильность или неправильность определяется чисто практическими вопросами. "Неправильность" такого подхода - геморрой с добавлением новых потомков.
Но раз приспичило - то где-то так:
C++
1
2
3
4
5
6
7
8
class Triangle;
class Rectangle;
class Figure
{
public:
    Triangle& ToTriangle() {return *dynamic_cast<Triangle*>(this);}
    Rectangle& ToRectangle() {return *dynamic_cast<Rectangle*>(this);}
};
Это простейший способ, по-хорошему надо проверять результат dynamic_cast и выбрасывать исключения в случае ошибки. Ну и разумеется, наследовать Triangle и Rectangle от Figure, плюс желательно в потомках скрывать преобразования.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
23.10.2011, 15:25
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
#include<iostream>
 
struct Triangle;
struct Rectangle;
 
class Figure
{
public:
    // создать метод доступа ToTriangle(), ToRectangle()
    Triangle ToTriangle();
    Rectangle ToRectangle();
};
struct Triangle  : Figure
{
    Triangle(const Figure&){}
    int GetArea() const { return 10;/*itsArea*/; }
};
struct Rectangle  : Figure
{
    Rectangle(const Figure&){}
    int GetPerimeter() const { return 100/*itsPerimeter*/; }
};
 
 Triangle Figure::ToTriangle(){
        return Triangle(*this);
 }
 
 Rectangle Figure::ToRectangle(){
        return Rectangle(*this);
}
int main()
{ 
    Figure pFigure;
    /*     вот тут должен открываться доступ к функциям Triangle.*/
    std::cout<<pFigure.ToTriangle().GetArea()<<std::endl;
    /*     вот тут должен открываться доступ к функциям Rectangle.*/
    std::cout<<pFigure.ToRectangle().GetPerimeter()<<std::endl;
}
Цитата Сообщение от Nick Alte Посмотреть сообщение
Это простейший способ, по-хорошему надо проверять результат dynamic_cast и выбрасывать исключения в случае ошибки
Угу, потому как тут преведение таким способом не возможно
1
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
23.10.2011, 16:32
Цитата Сообщение от Kastaneda Посмотреть сообщение
Угу, потому как тут преведение таким способом не возможно
А вот не надо мне, пожалуйста, рассказывать этих сказочек, а лучше смотреть внимательнее и правильно пользоваться конструкциями языка.
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
#include <iostream>
class Triangle;
class Rectangle;
class Figure {
public:
    Triangle& ToTriangle();
    Rectangle& ToRectangle();
    virtual ~Figure() {};
};
 
class Triangle: public Figure {
public:
    void GetArea() const {std::cout << "Triangle::GetArea" << std::endl;}
};
 
class Rectangle: public Figure {
public:
    void GetPerimeter() const {std::cout << "Rectangle::GetPerimeter" << std::endl;}
};
 
Triangle& Figure::ToTriangle()
{return *dynamic_cast<Triangle*>(this);}
 
Rectangle& Figure::ToRectangle()
{return *dynamic_cast<Rectangle*>(this);}
 
int main()
{
    Figure* figures[] = {new Rectangle(), new Triangle()};
    figures[0]->ToRectangle().GetPerimeter();
    figures[1]->ToTriangle().GetArea();
    delete figures[1];
    delete figures[0];
}
1
23.10.2011, 16:47

Не по теме:

Цитата Сообщение от Nick Alte Посмотреть сообщение
А вот не надо мне, пожалуйста, рассказывать этих сказочек, а лучше смотреть внимательнее и правильно пользоваться конструкциями языка.
так ты виртуальный деструктор добавил (о котором в посте выше и речи не было), тем самым обеспечив полиморфность!

0
85 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
23.10.2011, 16:58  [ТС]
Nick Alte, Отличный пример, возьму на заметку, но АБСТРАКТНЫЙ класс детектет.
0
Эксперт С++
1675 / 1047 / 174
Регистрация: 27.09.2009
Сообщений: 1,945
23.10.2011, 17:00
Цитата Сообщение от Kastaneda Посмотреть сообщение
так ты виртуальный деструктор добавил (о котором в посте выше и речи не было), тем самым обеспечив полиморфность!
Добавил. Это чтобы dynamic_cast работал. В кодепаде. Не проверял, но по-моему, Visual Studio умеет и без виртуальных методов typeinfo засаживать куда надо.
А вообще, бешеной-то собаке семь вёрст не крюк - я в том смысле, что смелые духом могут вообще плюнуть на полиморфность и проверку типов и преспокойно пользоваться reinterpret_cast, так что полиморфность сама по себе тут значения не имеет.
0
23.10.2011, 17:03

Не по теме:

Цитата Сообщение от Nick Alte Посмотреть сообщение
Добавил. Это чтобы dynamic_cast работал
Вот и я о чем:)

0
23.10.2011, 17:07

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
Вот и я о чем
Ну а я о том, что оно и без dynamic_cast сработает, и соответственно без полиморфизма. Просто я немного попараноил ради добавочных проверок, но можно-то и без них, на полном доверии и reinterpret_cast.

0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
23.10.2011, 17:10
Цитата Сообщение от Nick Alte Посмотреть сообщение
Не проверял, но по-моему, Visual Studio умеет и без виртуальных методов typeinfo засаживать куда надо.
нет, во всяком случае не должен
0
85 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
23.10.2011, 17:13  [ТС]
Kastaneda, Кстати
C++
1
 class Rectangle: public Figure
Если наследуется от Figure, то я могу методом "ToRectangle()->" обратится к членам базового класса. ToRectangle()->ToRectangle()->ToRectangle()..... это правильно?
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
23.10.2011, 17:24
Цитата Сообщение от res Посмотреть сообщение
ToRectangle()->ToRectangle()->ToRectangle()..... это правильно?
Ну такой код будет работать (в данном случае '->' заменить на '.'). А почему это должно быть не правильно?

возможны ведь и такие конструкции:
C++
1
dynamic_cast<Rectangle*>(dynamic_cast<Rectangle*>(dynamic_cast<Rectangle*>(this)));
только кто их будет писать?
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
23.10.2011, 17:24
Помогаю со студенческими работами здесь

Создание экземпляра класса-наследника для переменной с типом базового класса
Подскажите чайнику как создается экземпляр класса BC BaseClass BC = new DerivedClass(); Вопрос: BC - это экземпляр класса BaseClass...

Правда, что указатель класса-наследника не может указывать на объект класса-родителя?
Доброго времени суток! Пример кода ниже. Правда ли , что указатель класса-наследника не может указывать на объект класса-родителя? ...

Как обратиться из конструктора базового абстрактного класса к свойству-массиву класса наследника
Добрый день. Подскажите как обратиться из конструктора базового абстрактного класса к свойству-массиву из класса наследника. Вроде бы...

Создать для класса виртуальный метод, возвращающий уникальный идентификатор класса
В курсаче по ООП сказано создать для класса виртуальный метод,возвращающий уникальный идентификатор класса. Вопрос в том, что это такое?

Как сделать явное приведения переменной типа класса-наследника к типу базового класса?
Читал, что для этого нужно явное приведение к типу, но на практике выдаёт ошибку. Вот код: using System; using System.Linq; namespace...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru