Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705

Как преобразовать указатель на класс к указателю на асбтрактный класс?

26.03.2013, 02:35. Показов 1120. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Но тут есть одна тонкость- два промежуточных класса.

Вот код, надеюсь всё из него понятно.
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <stdio.h>
//++++++++++++++++++++++++++++++
 
class base  {
 public:
   virtual void f ()= 0;     
};
 
//+++++++++++++++++++++++++++++++
 
class pr_0: public base  {
// public:
//   void f ()= 0;     
};
 
//+++++++++++++++++++++++++++++++
 
class pr_1: public base  {
// public:
//   void f ()= 0;     
};
 
 
//+++++++++++++++++++++++++++++++
 
class rez: public pr_0,pr_1  {
 public:
   void f (){;};     
};
 
//+++++++++++++++++++++++++++++++
 
int main () {
 
 rez* p= new  rez; 
 
 
 //ПРОБЛЕМА В ЭТОМ УЧАСТКЕ КОДА. Я должен писать либо так,
 //либо base* b= (base*)(pr_0*)p, меж тем мне абсолютно  
 //всё равно через какой из интерфейсов (pr_0 или pr_1)  
 //я получу указатель на base. Ведь через указатель на   
 //base я смогу вызвать единственную функцию- f; она      
 //объявлен в base, реализована в rez, два транзитных    
 //интерфейса имеют к ней отношение как свинья к         
 //апельсинам. Тем не менее, надо их учесть, а смысл? Они
 //в эту функцию не привносят ничего нового, она через них 
 //транзитом идёт просто и всё.                          
 
 base* b= (base*)(pr_1*)p;
 
 //Вот так к сожалению писать нельзя, а хотелось бы. Чтобы
 //при взгляде на код было ясно: мне всё равно через какой
 //из интерфейсов pr_0 или pr_1 я получаю указатель на
 //base                     
 
 //base* b= (base*)p;
 
 b->f(); 
 
 
 getchar ();
 return 0;
}
ВЫ мне можете возразить: код слишком демонстрационный и компилятор не может учесть все фантазии пользователей. Согласен, тут pr_0 и pr_1 даром не нужны. Можно просто наследовать rez от base и всё. Что же, можно добавить в код практичности. Например, объявить в каждом из интерфейсов pr_0 и pr_1 по чистой виртуальной функции,
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
//+++++++++++++++++++++++++++++++
 
class pr_0: public base  {
 public:
  virtual void f_0 ()= 0;     
};
 
//+++++++++++++++++++++++++++++++
 
class pr_1: public base  {
 public:
  virtual void f_1 ()= 0;     
};
а реализовать их в rez. Просто я этого делать не стал, дабы не загромождать код. В этом случае проблема также остаётся актуальной и надуманной- ведь хоть наши интерфейсы теперь "полезные" (содержат объявления функций), они по прежнему не имеют отношения к f. Но тем не менее их надо учитывать при приведении типа! Смысл? f-то всё равно ОДНА!

Спасибо кто откликнется.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.03.2013, 02:35
Ответы с готовыми решениями:

Привести указатель на класс к указателю на void
Хай #pragma once #include &quot;list.h&quot;; #include &quot;Print.h&quot;; class Robot { public:

Как преобразовать класс из динамически сгенерированного кода в локальный класс?
Исходные данные: Форма, на ней кнопка, по нажатию на которую компилируется программа, совершает расчёты, возвращает результат. ...

Создать класс матрица Данный класс содержит указатель на int...
Помогите решить хотя бы часть задачи. Создать класс матрица Данный класс содержит указатель на int, размер строк и столбцов и...

2
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
26.03.2013, 03:00
Цитата Сообщение от kravam Посмотреть сообщение
//Вот так к сожалению писать нельзя, а хотелось бы. Чтобы
*//при взгляде на код было ясно: мне всё равно через какой
*//из интерфейсов pr_0 или pr_1 я получаю указатель на
*//base * * * * * * * * * *
//base* b= (base*)p;
виртуальное наследование

Цитата Сообщение от kravam Посмотреть сообщение
//Вот так к сожалению писать нельзя, а хотелось бы. Чтобы
*//при взгляде на код было ясно: мне всё равно через какой
*//из интерфейсов pr_0 или pr_1 я получаю указатель на
*//base
а вообще тут без вариантов - только через pr_0 ибо он наследуется публично
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
01.04.2013, 16:03  [ТС]
Исследуем дальше. Оказывается через какой класс pr_0 или pr_1 находить указатель на base- большая разница

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 base* b;
 
 b= (pr_0*)p;
 printf ("%x\n", b);
 //То же что и
 b= (base*)(pr_0*)p;
 printf ("%x\n", b);
 
 //+++++++++++++++++++++++++++++++
 
 b= (pr_1*)p;
 printf ("%x\n", b);
 //То же что и
 b= (base*)(pr_1*)p;
 printf ("%x\n", b);
данные разнятся.

Если в base объявить функцию, а определить её в rez и потом вызвать, вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 base* b;
 
 b= (pr_0*)p;
 printf ("%x\n", b);
 
 b= (base*)(pr_0*)p;
 printf ("%x\n", b);
 b-> f(); 
 
 b= (pr_1*)p;
 printf ("%x\n", b);
 
 b= (base*)(pr_1*)p;
 printf ("%x\n", b);
 b-> f();
то всё ж таки функция будет вызвана одна и та же. Это наталкивает на мысль, что вроде как получать указатель на base есть разница, но вроде как и нет (тело f ведь одно и то же). Пусть каждый интерпретирует как хочет, я лишь даю голые факты.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.04.2013, 16:03
Помогаю со студенческими работами здесь

Как преобразовать класс определенного типа в класс другого типа с входным типом
Создал 2 класса, которые служат аргументами для событий Public Class ItemAddedEventArgs(Of T) Sub New(Item As T) Me.Item...

Как в функции my_function преобразовать ссылку на базовый класс в ссылку на класс B или С
Всем привет, как в функции my_function преобразовать ссылку на базовый класс в ссылку на класс B или С ? class A { public: A(); ...

Есть класс A и класс B, класс B вложен в класс A и вложен в него, как классу B получить доступ к переменным класса A просто по имени?
На самом деле ничё фантастического я не прошу, ведь: template &lt;class T&gt; class matrix { friend class diagonal; ...

Как удалить объект класс из кучи по указателю?
Как удалить экземпляр класса из кучи по указателю? Есть простенький код: запускает два потока, один выделяет место для объектов и...

Как указателю на класс присвоить адрес класса?
Я пишу программу, и столкнулся с одной проблемой. У меня в функцию, передаётся в качестве параметра ссылка на объект класса, и далее мне...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru