2015-10-08 4 views
1

прочитайте следующую программу, которая использует reinterpret_cast.Может ли кто-нибудь объяснить, как реинтерпрет-листинг работает в этом коде

#include <iostream> 

class A 
{ 
    public: 
     A() : m_i(0) { } 
    protected: 
     int m_i; 
}; 

class B 
{ 
    public: 
     B() : m_d(0.0) { } 

    protected: 
     double m_d; 
}; 

class C : public A , public B 
{ 
    public: 
     C() : m_c('a') { } 
    private: 
     char m_c; 
}; 

int main() 
{ 
    C c; 
    A *pa = &c; 
    B *pb = &c; 

    bool z = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb)); 
    std::cout << z; 
    return 0; 
} 

После выполнения этой программы он печатает 0, может кто-нибудь объяснить, почему г приходит ложь в этой программе ??

ответ

5

Может кто-нибудь объяснить, как переосмысливать литая работает в этом коде

reinterpret_cast<char*>(pa) оценивающего к указателю типа char*, численное значение такое же, как у pa. Использование:

bool z = (pa == pb); 

приводит к ошибке компиляции, поскольку A и B не непосредственно связаны между собой. Использование

bool z = (reinterpret_cast<char*>(pa) == reinterpret_cast<char*>(pb)); 

позволяет сравнить численные значения pa и pb.

После запуска этой программы он печатает 0, может ли кто-нибудь объяснить, почему z идет ложно в этой программе?

Численные значения pa и pb не совпадают. Следовательно, результат. Вы можете использовать:

cout << "pa: " << std::hex << (void*)pa << std::endl; 
cout << "pb: " << std::hex << (void*)pb << std::endl; 

Чтобы распечатать эти значения и убедить себя, что они не одинаковы.

Если посмотреть на макет памяти в C, это выглядит примерно так:

+------+ 
| m_i |  // The A sub-object 
+------+ 
| m_d |  // The B sub-object 
+------+ 
| m_c |  
+------+ 

При использовании

C c; 
A* pa = &c; 
B* pb = &c; 

pa указывает на A к югу от объекта C и pb точек к объекту BC. Как видно из рисунка, существует смещение между под-объектом A и под-объектом B. Следовательно, численные значения pa и pb различны. Наиболее вероятно, что они будут отличаться на sizeof(m_i).

+0

@R Sahu, почему значение pa и pb приближается к другому. Они имеют одинаковый адрес значения c (& c) – luck

+0

Я не думаю, что 'bool z = (pa == pb);' будет компилироваться, поскольку 'A' и' B' не происходят друг от друга, и поэтому Указатель 'A *' не может быть напрямую сопоставлен с указателем 'B *', не отбрасывая их на общий тип данных, в этом случае 'char *'. –

+0

@RemyLebeau, вы правы. Спасибо что подметил это. –

0

reinterpret_cast - это то же самое, что и static_cast. reinterpret_cast происходит во время выполнения, а static_cast - во время компиляции. Это не имеет никакого значения в этом случае, но было бы иметь значение, если приведение было применено к объекту c.

A* pa = &reinterpret_cast<A&>(c); 
B* pb = &reinterpret_cast<B&>(c); 

сделает pa и pb одинаковыми. Несмотря на то, что вы эффективно написали делает неявное статического бросок:

A* pa = &static_cast<A&>(c); 
B* pb = &static_cast<B&>(c); 

И так как это делает Ра и Рb разные, это не имеет значения, что они позже «переосмыслили».

 Смежные вопросы

  • Нет связанных вопросов^_^