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

Тонкость с указателями - взятие указателя на базовый класс - C++

Восстановить пароль Регистрация
 
ZiminAS1990
 Аватар для ZiminAS1990
2 / 2 / 0
Регистрация: 27.07.2012
Сообщений: 31
13.12.2012, 19:53     Тонкость с указателями - взятие указателя на базовый класс #1
Как-то возник в голове вопрос:
пусть класс D наследует классы A и B. Если у меня есть объект D, я беру его адрес и типизирую его к базовым классам A и B. Получаю два указателя типа A* и B*. Будут ли они указывать на корректные объекты?

Я всегда предполагал, что конструкции типа:
Type1 *a = (Type1*)b;
это указания компилятору интерпретировать данные по указателю b как данные типа Type1. А значит, указатель "a" всегда должен указывать на ту же ячейку памяти что и указатель b.
Если так, то указатели A* и B* должны будут указывать на одну и ту же ячейку памяти, что приведёт к ошибке (это ведь должно быть два разных объекта!)

Решил проверить. Написал простую программу:
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
class A {
public:
A() : a(10), b(20) {}
double a;
double b;
};
 
class B {
public:
B() : c(30), d(40) {}
double c;
double d;
};
 
class D : public A, public B {
public:
D() : e(50), j(60) {}
double e;
double j;
};
 
int main()
{
D objD;
// Получим базовые классы от производного:
A *objA = (A*)&objD;
B *objB = (B*)&objD;
// Получим производный класс от базового:
D* objDFromA = (D*)objA;
D* objDFromB = (D*)objB;
objD.a = 100;
objD.c = 300;
return 0;
}
Получилось так, что указатели objA и objB указывают на РАЗНЫЕ ячейки памяти, не смотря на то, что они получены простой типизацией одного и того же указателя objD.
Как реализован этот механизм? Получается, что вычисление значений указателей objA и objB производится в процессе выполнения программы (для этого генерируются отдельные инструкции в исполняемом файле)?
Это стандартный трюк и его можно безбоязненно использовать? Или не все компиляторы это поддерживают? (я использовал g++)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.12.2012, 19:53     Тонкость с указателями - взятие указателя на базовый класс
Посмотрите здесь:

Написать обработчик исключений ситуации при преобразовании указателя на класс B до указателя на абстрактный класс А ... C++
C++ typeid определяет тип указателя на базовый класс, как тип "базовый класс". Вне зависимости от присвоенного ему значения
Абстрактный базовый класс C++
Абстрактный базовый класс C++
Указатели в базовом классе на базовый класс и производный класс C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
soon
 Аватар для soon
2536 / 1301 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
13.12.2012, 21:38     Тонкость с указателями - взятие указателя на базовый класс #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
#include <iostream>
 
struct Foo
{
    virtual ~Foo()
    {
 
    }
};
 
struct Bar
{
    virtual ~Bar()
    {
 
    }
};
 
struct Baz: public Foo, public Bar
{
 
};
 
int main()
{
    Baz baz;
 
    auto foo_dynamic = dynamic_cast<Foo*>(&baz);
    auto bar_dynamic = dynamic_cast<Bar*>(&baz);
 
    std::cout << foo_dynamic << ' ' << bar_dynamic << std::endl;
 
    auto foo_reinterpret = reinterpret_cast<Foo*>(&baz);
    auto bar_reinterpret = reinterpret_cast<Bar*>(&baz);
 
    std::cout << foo_reinterpret << ' ' << bar_reinterpret << std::endl;
 
    return 0;
}
Не используйте в плюсах приведение в стиле Си.
ZiminAS1990
 Аватар для ZiminAS1990
2 / 2 / 0
Регистрация: 27.07.2012
Сообщений: 31
14.12.2012, 10:07  [ТС]     Тонкость с указателями - взятие указателя на базовый класс #3
Спасибо!
Нужно будет по разбираться с этим
WhiteP
605 / 203 / 23
Регистрация: 20.11.2012
Сообщений: 419
14.12.2012, 11:06     Тонкость с указателями - взятие указателя на базовый класс #4
Почитай - хорошая статья в тему:
http://devdoc.web-ide.ru/index.php/c...rtual_base.htm
vxg
Модератор
 Аватар для vxg
2639 / 1650 / 156
Регистрация: 13.01.2012
Сообщений: 6,213
14.12.2012, 16:42     Тонкость с указателями - взятие указателя на базовый класс #5
Цитата Сообщение от soon Посмотреть сообщение
Не используйте в плюсах приведение в стиле Си
...или думайте что делаете. ничто не мешает использовать стиль Си.
soon
 Аватар для soon
2536 / 1301 / 81
Регистрация: 09.05.2011
Сообщений: 3,086
Записей в блоге: 1
14.12.2012, 18:00     Тонкость с указателями - взятие указателя на базовый класс #6
Цитата Сообщение от vxg Посмотреть сообщение
ничто не мешает использовать стиль Си.
Кастование в стиле C++ вносит определенную ясность. Да и смешивать два языка не есть хорошо.
yekka
384 / 148 / 8
Регистрация: 12.05.2011
Сообщений: 450
14.12.2012, 19:58     Тонкость с указателями - взятие указателя на базовый класс #7
очевидно, что при множественном наследовании два объекта-предка не могут иметь один и тот же адрес, поэтому для преобразования указателя на дочерний объект к указателю на второй родительский объект (и обратно) к указателю необходимо будет добавить некоторое смещение.

Вообще, сишное приведение типов сначала пытается применить static_cast, а если не получается, то использует reinterpret_cast. В твоем случае, очевидно, достаточно static_cast'а, поэтому преобразование будет "умным" (т.е. с добавлением нужного смещения при необходимости). А если явно запросить reinterpret_cast, то смещение добавлено не будет и в общем случае получим нерабочий указатель.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.12.2012, 20:53     Тонкость с указателями - взятие указателя на базовый класс
Еще ссылки по теме:

Как при помощи указателя на базовый класс обратится к полю наследуемого класса? C++
Неоднозначный базовый класс C++
C++ Как в функции my_function преобразовать ссылку на базовый класс в ссылку на класс B или С

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

Или воспользуйтесь поиском по форуму:
ZiminAS1990
 Аватар для ZiminAS1990
2 / 2 / 0
Регистрация: 27.07.2012
Сообщений: 31
14.12.2012, 20:53  [ТС]     Тонкость с указателями - взятие указателя на базовый класс #8
Цитата Сообщение от WhiteP Посмотреть сообщение
Почитай - хорошая статья в тему:
http://devdoc.web-ide.ru/index.php/c...rtual_base.htm
О! Спасибо большое! Низкоуровневые вещи - это как раз то, что чаще всего вносит полную ясность без лишних абстракций.
Yandex
Объявления
14.12.2012, 20:53     Тонкость с указателями - взятие указателя на базовый класс
Ответ Создать тему
Опции темы

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