LINUX.ORG.RU

dynamic_cast или что-то по-проще.


0

1

Простой тестовый код:

#include <cstdio>

class A {
        public:
                virtual void test() = 0;
};

class B: public A {
        public:
                virtual void test() {};
};

class C: public B {
        public:
                virtual void test() {};
};

int main() {
        B *cB = new B();
        C *cC = new C();

        A *base_p=NULL;
        printf("pointers  base_p=%p cB=%p cC=%p\n", base_p, cB, cC);

        C *p2=NULL;

        base_p = (A *) cC;
        p2 = (C *) base_p;
        printf("pointers  base_p=%p p2=%p\n", base_p, p2);

        base_p = (A *) cB;
        p2 = (C *) base_p;
        printf("pointers  base_p=%p p2=%p\n", base_p, p2);

        return 0;
}

Непонятно почему в конце, p2 после приведения к типу (С *) указывает на объект который (В *) и вообще непонятно почему он привелся, ведь по факту не должен.

Ткните, если можно, где почитать о том, почему так происходит.

P.S. С dynamic_cast'ом конечно же все работает верно.

★★★★★

Последнее исправление: Jetty (всего исправлений: 1)

Ну и вывод рабочий:

pointers  base_p=(nil) cB=0xaf8010 cC=0xaf8030 
pointers  base_p=0xaf8030 p2=0xaf8030
pointers  base_p=0xaf8010 p2=0xaf8010

Jetty ★★★★★
() автор топика

>Непонятно почему в конце, p2 после приведения к типу (С *) указывает на объект который (В *) и вообще непонятно почему он привелся, ведь по факту не должен.

Потому что ты так сам написал. Это не PHP и не жаба, это Си, здесь нужно самому следить за своими указателями.

Ткните, если можно, где почитать о том, почему так происходит.

Керниган/Ритчи «Язык Си», Фомин-Подбельский «Язык Си»

ttnl ★★★★★
()
Ответ на: комментарий от Begemoth

>И давно в C появились классы?

А при чем тут, классы? Человек не знает элементарных указателей, в этом вся проблема.

ttnl ★★★★★
()
Ответ на: комментарий от ttnl

да вроде знает,
он не знает что такое RTTI, полиморфные классы и виртуальный деструктор .....
Я тоже мало в этом соображаю :(

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от ttnl

Скорее в данном конкретном случае я не понимаю каким образом работает C-style привидение типов. Неужели так «в лоб» ? :)

Jetty ★★★★★
() автор топика
Ответ на: комментарий от ttnl

Человек не знает элементарных указателей, в этом вся проблема.

Где ты это увидел? Он не знает правил преобразования указателей на экземпляры классов.

Begemoth ★★★★★
()
Ответ на: комментарий от Jetty

привидение типов

что вы такого с типами делали!?

Неужели так «в лоб»

Да, как reinterpret_cast (только reinterpret_cast нельзя применять вместо static_cast или const_cast, а С-шные приведения типов можно).

Begemoth ★★★★★
()
Ответ на: комментарий от Jetty

>Неужели так «в лоб»?

Конечно, это же обычное преобразование.

ttnl ★★★★★
()
Ответ на: комментарий от Boy_from_Jungle

а за него вообще руки не отрывают?

Вроде как он иногда нужен в сильно низкоуровневых вещах. Так что если прокомменрировано его использование, ИМХО всё нормально. А вот за сишные приведения типов отрывать руки надо однозначно.

Begemoth ★★★★★
()

Есть такой принцип, мусор на входе - мусор на выходе. Он применим к примеру частично.

Это обратная сторона гибкости С. Слишком много доверия програмисту компилятором. Вот на аде, например, компилятор тебя пошлёт куда подальше с таким кодом. И на яве думаю тоже. А в С - нет. Потому-что программисту виднее.

И именно по этому в С++ не рекомендуют использовать С style type casting.

mi_estas
()
Ответ на: комментарий от Begemoth

можно ведь на void это всё привести, а уже потом к какой-то-endian последовательности.

Boy_from_Jungle ★★★★
()
Ответ на: комментарий от Boy_from_Jungle

Там сплошные reinterpret_cast'ы и const_cast'ы. Причем их использование вполне оправдано.

elverion
()

Господа, всем спасибо :)
На самом деле ожидал что компилятор и правда будет как-то это контролировать на этапе компиляции. Думал что g++ немножечко «умнее»/строже gcc.

Еще раз спасибо за уделенное время :)

Jetty ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.