2016-04-17 4 views
0

Тип изменен, но я думаю, *(int*)&b и (int*)*(int*)&b должны указывать на тот же адрес.О виртуальных функциях, почему печатаются значения * (int *) & b и (int *) * (int *) & b разные?

Вот исходный файл. Было бы признательно, если вы можете мне помочь в том, почему два выхода линии A отличаются друг от друга.

#include "stdafx.h" 
#include <iostream>  
#include <stdlib.h> 
using namespace std; 
typedef void (*fun)(); 
class Base 
{ 
public: 
    virtual void f(){cout<<'f'<<endl;} 
    virtual void g(){cout<<'g'<<endl;} 
    virtual void h(){cout<<'h'<<endl;} 
}; 
int _tmain(int argc, _TCHAR* argv[]) 
{ 
    Base b; 
    cout<<*(int*)&b<<endl<<(int*)*(int*)&b<<endl; //A 
    return 0; 
} 
+0

Пожалуйста, обратите внимание на мой ответ для более подробного объяснения относительно различной мощности. –

ответ

0

Прежде всего, ваш вопрос не имеет никакого отношения к виртуальным функциям. Насколько отличается вывод идет, причина заключается в следующем:

  1. Выражения *(int*)&b принимает адрес объекта b, отбрасывает его в указатель на целое число, а затем разыменовывает его, таким образом производя целочисленное значение.

  2. Выражение (int*)*(int*)&b выполняет все описанные выше шаги, но затем принимает это целочисленное значение и переводит его в целочисленный указатель. Хотя он имеет то же числовое значение, он теперь является типом указателя, который заставляет его отображаться в шестнадцатеричной форме, когда он печатается с использованием оператора <<, тогда как целочисленное значение будет отображаться в десятичной форме. Именно по этой причине вы видите разные результаты.

Обратите внимание, что вы не должны преобразовывать объект какого-либо класса, чтобы его распечатать. Если вы хотите напечатать объект с помощью <<, вам необходимо перегрузить этот оператор. Пожалуйста, обратите внимание на оператор перегрузки:

http://en.cppreference.com/w/cpp/language/operators

+0

Я понял. Я просто хотел получить адрес первой виртуальной функции ... В любом случае, я думаю, вы дали мне прекрасный ответ. Большое спасибо. –

+0

@PandaLee Добро пожаловать! Если вы считаете, что ответ был хорошим, подумайте о том, чтобы он был принят как знак благодарности за мое время и усилия. Желаем удачи в изучении C++. –

0

Игнорируя тот факт, что ваш код не определена, разница в том, что одно выражение является указателем, а другой нет.

Замените Base b; на int b;, чтобы сделать его понятным (и четко определено).

Тогда *(int*)&b эквивалентен *&b, то есть b, a int.
С другой стороны, (int*)*(int*)&b эквивалентен (int*)*&b, который составляет (int*)b, a int*.

+0

Однако я не могу cout << b; на VS2010, но я могу cout << * (int *) & b. Так что это имеет значение. Большое спасибо за то, что вы ответили на мой 1-й вопрос здесь, и это было бы так любезно, если вы сможете это объяснить. –

+0

@PandaLee Вы можете 'cout << b;', если вы определили подходящую перегрузку 'operator <<'. – molbdnilo

+0

Я понял. Большое спасибо, еще раз. –