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

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

Войти
Регистрация
Восстановить пароль
 
BESSON_off
 Аватар для BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 338
#1

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

27.08.2013, 18:19. Просмотров 504. Ответов 9
Метки нет (Все метки)

Здравствуйте!

Изучая возможности наследования столкнулся со следующим утверждением: "Если для объекта производного класса объявить какой-то метод, который не принадлежит базовому классу, то невозможно получить доступ к этому методу, используя указатель на базовый класс, если только этот указатель не будет явно преобразован в указатель производного класса. Всегда можно преобразовать любой указатель базового класса в указатель производного класса".
Вот пример:
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()?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.08.2013, 18:19     Как явно преобразовать указатель?
Посмотрите здесь:

C++ Указатель на указатель - разница способов
C++ Задача на указатели.Указатель на указатель.
указатель на указатель или присваивание объекта C++
Как преобразовать указатель на класс к указателю на асбтрактный класс? C++
C++ Преобразовать указатель в float
C++ Указатель на имя файла как аргумент функции. Как реализовать?
C++ Как объявить указатель на массив через typedef и как инициализировать такой тип
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lemegeton
 Аватар для lemegeton
2915 / 1344 / 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;
}
Убежденный
Системный программист
 Аватар для Убежденный
14639 / 6600 / 1045
Регистрация: 02.05.2013
Сообщений: 10,873
Завершенные тесты: 1
27.08.2013, 18:49     Как явно преобразовать указатель? #3
Правильный способ - использовать dynamic_cast.
Он умеет проверять тип указателя/ссылки во время выполнения программы, и
возвращает NULL/бросает исключение, если объект на самом деле не является
производным классом.
Croessmah
Модератор
Эксперт CЭксперт С++
 Аватар для Croessmah
12529 / 7091 / 797
Регистрация: 27.09.2012
Сообщений: 17,500
Записей в блоге: 2
Завершенные тесты: 1
27.08.2013, 18:50     Как явно преобразовать указатель? #4
Цитата Сообщение от Убежденный Посмотреть сообщение
Правильный способ - использовать dynamic_cast.
dynamic_cast применяется для полиморфных типов.
Убежденный
Системный программист
 Аватар для Убежденный
14639 / 6600 / 1045
Регистрация: 02.05.2013
Сообщений: 10,873
Завершенные тесты: 1
27.08.2013, 19:07     Как явно преобразовать указатель? #5
В примере топикстартера подразумевается наличие виртуальных методов, иначе работать с
производными классами через указатель или ссылку на базу не имеет смысла.
Kuzia domovenok
 Аватар для Kuzia domovenok
1886 / 1741 / 117
Регистрация: 25.03.2012
Сообщений: 5,916
Записей в блоге: 1
27.08.2013, 19:58     Как явно преобразовать указатель? #6
Цитата Сообщение от Убежденный Посмотреть сообщение
В примере топикстартера подразумевается наличие виртуальных методов
где?

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

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

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

При вынесении определения всегда ли нужно указывать функцию как inline явно? C++
C++ Как можно явно вызвать оператор преобразования?
C++ Указатель на указатель и Нарушение прав доступа
Как освободить память занимаемую вектором и явно вернуть системе? C++
C++ Переменная в явно загруженной DLL

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

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

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