Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
res
56 / 9 / 1
Регистрация: 05.04.2010
Сообщений: 143
#1

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

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

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

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

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

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

Вызов конструктора базового класса из класса-наследника - C++
Можно ли вне списка инициализации вызвать конструктор базового класса ? class A { int a; public: A(int c):a(c){} ...

Метод наследника? - C++
Я не очень силен в наследовании в С++... Пусть у меня есть класс наследника и есть метод такой же как и у родителя... Как мне сначала...

11
Nick Alte
Эксперт С++
1646 / 1018 / 120
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 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, плюс желательно в потомках скрывать преобразования.
0
Kastaneda
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,491
Записей в блоге: 2
Завершенные тесты: 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 и выбрасывать исключения в случае ошибки
Угу, потому как тут преведение таким способом не возможно
1
Nick Alte
Эксперт С++
1646 / 1018 / 120
Регистрация: 27.09.2009
Сообщений: 1,945
Завершенные тесты: 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];
}
1
Kastaneda
23.10.2011, 16:47
  #5

Не по теме:

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

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

Не по теме:

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

0
Nick Alte
23.10.2011, 17:07
  #9

Не по теме:

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

0
alex_x_x
бжни
2454 / 1659 / 84
Регистрация: 14.05.2009
Сообщений: 7,162
23.10.2011, 17:10 #10
Цитата Сообщение от Nick Alte Посмотреть сообщение
Не проверял, но по-моему, Visual Studio умеет и без виртуальных методов typeinfo засаживать куда надо.
нет, во всяком случае не должен
0
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()..... это правильно?
0
Kastaneda
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,491
Записей в блоге: 2
Завершенные тесты: 1
23.10.2011, 17:24 #12
Цитата Сообщение от res Посмотреть сообщение
ToRectangle()->ToRectangle()->ToRectangle()..... это правильно?
Ну такой код будет работать (в данном случае '->' заменить на '.'). А почему это должно быть не правильно?

возможны ведь и такие конструкции:
C++
1
dynamic_cast<Rectangle*>(dynamic_cast<Rectangle*>(dynamic_cast<Rectangle*>(this)));
только кто их будет писать?
1
23.10.2011, 17:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
23.10.2011, 17:24
Привет! Вот еще темы с ответами:

Конструктор класса наследника - C++
Я не могу понять свою ошибку к примеру если пишу так все нормально class one { public: one(); };

Вывод из класса наследника - C++
У меня получается вывод из главного класса, а когда вывожу через функцию из класса наследника выдает ошибку, из-за чего так???? хоты вывожу...

Не работает конструктор наследника класса - C++
Есть класс: template &lt;class T&gt; class HashTable { HashTable(int _size) { size = _size; for (int i = 0; i &lt;...

Вывод переменной из наследника класса - C++
Здравствуйте. Как можно вывести значение переменной класса из наследника, изменив это значение в нём? Таким методом, как я пробую, значение...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru