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

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

Восстановить пароль Регистрация
 
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
23.10.2011, 14:42     создать метод доступа к функциям класса-наследника #1
Допустим, есть базовый класс Фигура и наследники "Треугольник", "Квадрат". Мне нужно создать метод доступа к функциям наследника.
Просьба не говорить: "это не правильный подход к ООП, юзай абстрактный метод". Мне нужна именна такая реализация (Агрегирование)

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();
}
Пытался сам реализовать с приведениями типов. Покажите свою версию реализаций доступа(без ссылок на сторонние ресурсы)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
23.10.2011, 14:42     создать метод доступа к функциям класса-наследника
Посмотрите здесь:

Не работает конструктор наследника класса C++
C++ Метод наследника?
Вывод из класса наследника C++
Конструктор класса наследника C++
Вызов конструктора базового класса из класса-наследника C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
23.10.2011, 15:08     создать метод доступа к функциям класса-наследника #2
Правильность или неправильность определяется чисто практическими вопросами. "Неправильность" такого подхода - геморрой с добавлением новых потомков.
Но раз приспичило - то где-то так:
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, плюс желательно в потомках скрывать преобразования.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
23.10.2011, 15:25     создать метод доступа к функциям класса-наследника #3
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 и выбрасывать исключения в случае ошибки
Угу, потому как тут преведение таким способом не возможно
Nick Alte
Эксперт С++
1590 / 982 / 115
Регистрация: 27.09.2009
Сообщений: 1,897
Завершенные тесты: 1
23.10.2011, 16:32     создать метод доступа к функциям класса-наследника #4
Цитата Сообщение от 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];
}
Kastaneda
23.10.2011, 16:47
  #5

Не по теме:

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

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

Не по теме:

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

Nick Alte
23.10.2011, 17:07
  #9

Не по теме:

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

alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
23.10.2011, 17:10     создать метод доступа к функциям класса-наследника #10
Цитата Сообщение от Nick Alte Посмотреть сообщение
Не проверял, но по-моему, Visual Studio умеет и без виртуальных методов typeinfo засаживать куда надо.
нет, во всяком случае не должен
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
23.10.2011, 17:13  [ТС]     создать метод доступа к функциям класса-наследника #11
Kastaneda, Кстати
C++
1
 class Rectangle: public Figure
Если наследуется от Figure, то я могу методом "ToRectangle()->" обратится к членам базового класса. ToRectangle()->ToRectangle()->ToRectangle()..... это правильно?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.10.2011, 17:24     создать метод доступа к функциям класса-наследника
Еще ссылки по теме:

Дружественный метод класса и ошибка доступа C++
Создание базового класса и наследника C++
C++ Вызов членов и объектов с наследника класса

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

Или воспользуйтесь поиском по форуму:
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
23.10.2011, 17:24     создать метод доступа к функциям класса-наследника #12
Цитата Сообщение от res Посмотреть сообщение
ToRectangle()->ToRectangle()->ToRectangle()..... это правильно?
Ну такой код будет работать (в данном случае '->' заменить на '.'). А почему это должно быть не правильно?

возможны ведь и такие конструкции:
C++
1
dynamic_cast<Rectangle*>(dynamic_cast<Rectangle*>(dynamic_cast<Rectangle*>(this)));
только кто их будет писать?
Yandex
Объявления
23.10.2011, 17:24     создать метод доступа к функциям класса-наследника
Ответ Создать тему
Опции темы

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