Что означает `vcall '{0, {flat}}' в следующем примере? - PullRequest
0 голосов
/ 13 марта 2009

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

Давайте сначала проверим код:

#include <string>
#include <map>
#include <iostream.h>

class MyClass
{
public:

    virtual  int Func()
    {
        return 0;
    }

    int Func2()
    {
        return 0;
    }

};

class MyClass2 :  public MyClass
{
public:

    int Func( )
    {
        return 1;
    }

    int Func2()
    {
        return 1;
    }

};

class Processor
{
 private:
      typedef int (MyClass::*MemFuncGetter)();
      static std::map<std::string, MemFuncGetter> descrToFuncMap;

 public:
        static void Initialize();
        void Process(MyClass* m, const std::string&);

};

std::map<std::string, Processor::MemFuncGetter> Processor::descrToFuncMap;
void Processor::Initialize()
{

     descrToFuncMap["Func"]=&MyClass::Func;
     descrToFuncMap["Func2"]=&MyClass::Func2;
};

void Processor::Process(MyClass* ms, const std::string& key)
{
    std::map<std::string, MemFuncGetter>::iterator found = descrToFuncMap.find(key);
     if(found != descrToFuncMap.end())
     {
        MemFuncGetter memFunc = found->second;
        int dResult = (ms->*memFunc)();
        cout << "Result is : "<< dResult <<endl;
      }
 }


int main(int argc, char* argv[])
{
    Processor::Initialize();
    Processor p;

    MyClass *pMC2 = new MyClass2;
    p.Process(pMC2, "Func");
    p.Process(pMC2, "Func2");

    delete pMC2;
    pMC2 = NULL;

    return 0;
}

В этом примере результат, как и ожидалось:

Result is : 1
Result is : 0

Но когда я отлаживал с помощью отладчика VC 6 и наблюдал значение memFunc в Processor :: Process и нашел следующие значения:

In p.Process (pMC2, "Func"); звоните

memFunc 0x004011bd [thunk]:`vcall'{0,{flat}}' 

In p.Process (pMC2, "Func2"); звоните

memFunc 0x0040118b MyClass::Func2(void)

Я не понял thunk и flat в "[thunk]:` vcall '{0, {flat}} "? Может ли кто-нибудь помочь мне понять внутренности здесь?

Ответы [ 2 ]

3 голосов
/ 13 марта 2009

В WikiPedia есть довольно подробное объяснение того, что означает thunk.

http://en.wikipedia.org/wiki/Thunk

Суть thunk - это механизм доступа к виртуальной таблице C ++ во время выполнения. Это настроено для вызова соответствующей виртуальной функции для типа времени выполнения объекта.

Что касается vcall {0, {flat}}, я не уверен на 100%. Мое предположение состоит в том, что он сообщает о значениях, по которым thunk получает доступ к методу.

  • 0: смещение в виртуальной таблице
  • {flat}: иерархия наследования плоская, а не кратная
1 голос
/ 14 марта 2009

Различные обозначения объясняются тем, что указатели на функции-члены должны иметь возможность обрабатывать различные виртуальные и не виртуальные функции-члены (хотя и не статические функции-члены), а также должны иметь возможность обрабатывать функции-члены, которые принадлежат классу, с помощью различных форм. наследования (публичное, частное и / или виртуальное).

Лучшая статья, с которой я столкнулся, объясняющая, как работают указатели на функции-члены, - это Дуга Клагстона «Указатели на функции-члены и максимально быстрые делегаты C ++» в Project Code.

Вы, вероятно, догадались бы, что «указатель на функцию-член», как и обычный указатель на функцию, просто содержит указатель кода. Ты был бы неправ. Почти во всех компиляторах указатель на функцию-член больше, чем указатель на функцию. Наиболее странно, что в Visual C ++ указатель на функцию-член может иметь длину 4, 8, 12 или 16 байт, в зависимости от природы класса, с которым он связан, и в зависимости от того, какие настройки компилятора используются! Указатели на функции-члены более сложны, чем вы могли ожидать.

Это не легко читать, но стоит - информацию трудно найти где-либо еще. Хорошее прочтение этой статьи поможет вам понять, что на самом деле говорит отладчик, когда показывает такие вещи, как

[thunk]:`vcall'{0,{flat}}'

Ответ ДжаредПара , вероятно, в значительной степени на высоте - статья Clugstons даст вам остальную часть истории.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...