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

Как явно преобразовать указатель? - C++

Восстановить пароль Регистрация
 
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
27.08.2013, 18:19     Как явно преобразовать указатель? #1
Здравствуйте!

Изучая возможности наследования столкнулся со следующим утверждением: "Если для объекта производного класса объявить какой-то метод, который не принадлежит базовому классу, то невозможно получить доступ к этому методу, используя указатель на базовый класс, если только этот указатель не будет явно преобразован в указатель производного класса. Всегда можно преобразовать любой указатель базового класса в указатель производного класса".
Вот пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std; 
 
class One
{
};
 
class Two : public One
{
public:
    void func() {cout << "\n0(-_o)0\n";}
};
 
int main()
{
One * ptr = new Two;
//(*ptr).Two::func();
return 0;
}
Каким образом можно, преобразовав указатель, вызвать функцию func()?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lemegeton
 Аватар для lemegeton
2908 / 1337 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
27.08.2013, 18:33     Как явно преобразовать указатель? #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
class One {
};
 
class Two : public One {
 public:
  void func() {
    std::cout << "\n0(-_o)0\n";
  }
};
 
int main(int, char**) {
  One * ptr = new Two;
  // лучше так
  static_cast<Two*>(ptr)->func();
  // можно так
  ((Two*)ptr)->func();
  return 0;
}
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,296
Завершенные тесты: 1
27.08.2013, 18:49     Как явно преобразовать указатель? #3
Правильный способ - использовать dynamic_cast.
Он умеет проверять тип указателя/ссылки во время выполнения программы, и
возвращает NULL/бросает исключение, если объект на самом деле не является
производным классом.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11803 / 6782 / 766
Регистрация: 27.09.2012
Сообщений: 16,834
Записей в блоге: 2
Завершенные тесты: 1
27.08.2013, 18:50     Как явно преобразовать указатель? #4
Цитата Сообщение от Убежденный Посмотреть сообщение
Правильный способ - использовать dynamic_cast.
dynamic_cast применяется для полиморфных типов.
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,296
Завершенные тесты: 1
27.08.2013, 19:07     Как явно преобразовать указатель? #5
В примере топикстартера подразумевается наличие виртуальных методов, иначе работать с
производными классами через указатель или ссылку на базу не имеет смысла.
Kuzia domovenok
 Аватар для Kuzia domovenok
1882 / 1737 / 116
Регистрация: 25.03.2012
Сообщений: 5,907
Записей в блоге: 1
27.08.2013, 19:58     Как явно преобразовать указатель? #6
Цитата Сообщение от Убежденный Посмотреть сообщение
В примере топикстартера подразумевается наличие виртуальных методов
где?

Добавлено через 1 минуту
Цитата Сообщение от Убежденный Посмотреть сообщение
иначе работать с
производными классами через указатель или ссылку на базу не имеет смысла.
совсем нет. Он же кастует указатели. А после каста вполне может вызывать любые методы, хоть виртуальные, хоть нет или вообще (как в примере) методы, которых нет в базовом!
Убежденный
Системный программист
 Аватар для Убежденный
14175 / 6190 / 981
Регистрация: 02.05.2013
Сообщений: 10,296
Завершенные тесты: 1
27.08.2013, 20:57     Как явно преобразовать указатель? #7
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Он же кастует указатели. А после каста вполне может вызывать любые методы, хоть виртуальные, хоть нет или вообще (как в примере) методы, которых нет в базовом!
Ну и в чем смысл такого (в отсутствии виртуальных методов) ?
zer0mail
2177 / 1860 / 187
Регистрация: 03.07.2012
Сообщений: 6,617
Записей в блоге: 1
27.08.2013, 21:40     Как явно преобразовать указатель? #8
Цитата Сообщение от Убежденный Посмотреть сообщение
Ну и в чем смысл такого (в отсутствии виртуальных методов) ?
Вопрос, конечно, интересный. Даже 2 вопроса:
1. Будет ли это работать
2. Зачем это надо

Если мы работаем как с объектами базового класса, так и с объектами прозводных классов. И у нас есть потребность добавить новые методы в базовый класс (но доступа к нему и прочим наследникам нет). Тогда делаем своего наследника, добавляем в нем методы и используем для базового ( и для "чужих" наследников). Т.е. этот метод нам полезен и он мог бы быть в базовом классе (все необходимые данные там есть), но его там нет...

Чисто для примера: базовый класс двусвязный список и куча наследников, есть метод "получить следующий объект". А метода "получить предыдущий" нет...
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11803 / 6782 / 766
Регистрация: 27.09.2012
Сообщений: 16,834
Записей в блоге: 2
Завершенные тесты: 1
28.08.2013, 02:34     Как явно преобразовать указатель? #9
Цитата Сообщение от Убежденный Посмотреть сообщение
В примере топикстартера подразумевается наличие виртуальных методов
Согласен. Но подобный пример с dynamic_cast скорее всего даже не скомпилируется потому что нет полиморфизма, поэтому и написал
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.08.2013, 20:06     Как явно преобразовать указатель?
Еще ссылки по теме:

Расскажите, как здесь работает указатель на указатель? C++
Почему указатель на указатель объявляется как float **A; C++
C++ Как правильно удалять выделенную память под указатель на указатель?

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

Или воспользуйтесь поиском по форуму:
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 329
28.08.2013, 20:06  [ТС]     Как явно преобразовать указатель? #10
Спасибо, что помогли разобраться!
Yandex
Объявления
28.08.2013, 20:06     Как явно преобразовать указатель?
Ответ Создать тему
Опции темы

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