Указатели на виртуальные функции членства.Как это работает?

Ну, все, что я могу сказать, - то, что я полностью согласен. Бэкенд является большим, но UI сосет. Потоковая функциональность является большой, потому что она делает слияние не более мозговитого, поскольку все изменения от родительских потоков автоматически распространены всем детям. Я записал сообщение о Accurev UI, который объясняет большинство недостатков, с которыми я сталкивался в течение прошлых 2 лет.

26
задан 6 July 2009 в 15:25
поделиться

3 ответа

Here is way too much information about member function pointers. There's some stuff about virtual functions under "The Well-Behaved Compilers", although IIRC when I read the article I was skimming that part, since the article is actually about implementing delegates in C++.

http://www.codeproject.com/KB/cpp/FastDelegate.aspx

The short answer is that it depends on the compiler, but one possibility is that the member function pointer is implemented as a struct containing a pointer to a "thunk" function which makes the virtual call.

10
ответ дан 28 November 2019 в 07:42
поделиться

It works because the Standard says that's how it should happen. I did some tests with GCC, and it turns out for virtual functions, GCC stores the virtual table offset of the function in question, in bytes.

struct A { virtual void f() { } virtual void g() { } }; 
int main() { 
  union insp { 
    void (A::*pf)();
    ptrdiff_t pd[2]; 
  }; 
  insp p[] = { { &A::f }, { &A::g } }; 
  std::cout << p[0].pd[0] << " "
            << p[1].pd[0] << std::endl;
}

That program outputs 1 5 - the byte offsets of the virtual table entries of those two functions. It follows the Itanium C++ ABI, which specifies that.

22
ответ дан 28 November 2019 в 07:42
поделиться

I'm not entirely certain, but I think it's just regular polymorphic behavior. I think that &A::f actually means the address of the function pointer in the class's vtable, and that's why you aren't getting a compiler error. The space in the vtable is still allocated, and that is the location you are actually getting back.

This makes sense because derived classes essentially overwrite these values with pointers to their functions. This is why (a->*f)() works in your second example - f is referencing the vtable that is implemented in the derived class.

1
ответ дан 28 November 2019 в 07:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: