0

i got a confuse about how does c++ compiler handle "this" pointer in virtual function, my code:

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>

using namespace std;



class A {
        public:
                void print_A(void) {
                        cout << "A::THIS = " << this << endl;

                        return;
                }

                int a;

        virtual ~A(void) {
                return;
        }
};

class B {
        public:
                virtual void print(void) {
                        cout << "B::THIS = " << this << endl;

                        return;
                }

                int b;
};

class C: public A, public B {
        public:
                void print(void) {
                        cout << "C::THIS = " << this << endl;

                        return;
                }

                int c;
};


class D {
        public:

                int d;

                virtual ~D(void) {
                        return;
                }
};


class E: public D, public C {
        public:
                int e;

                virtual ~E(void) {
                        return;
                }
};

void global_print(B *pb) {
        cout << "pb = " << pb << endl;
        pb->print();

        return;
}

int main(int argc, char *argv[]) {

        E e;
        A *pa = &e;
        B *pb = &e;
        C *pc = &e;
        D *pd = &e;
        E *pe = &e;


        cout << "pa = " << pa << endl;
        cout << "pb = " << pb << endl;
        cout << "pc = " << pc << endl;
        cout << "pd = " << pd << endl;
        cout << "pe = " << pe << endl;

        pb->print();
        pc->print();
        pe->print();


        global_print(&e);
        return 0;

this is result compiled with g++ in my linux:

pa = 0x7ffc1e7c7a80
pb = 0x7ffc1e7c7a90
pc = 0x7ffc1e7c7a80
pd = 0x7ffc1e7c7a70
pe = 0x7ffc1e7c7a70
C::THIS = 0x7ffc1e7c7a80
C::THIS = 0x7ffc1e7c7a80
C::THIS = 0x7ffc1e7c7a80
pb = 0x7ffc1e7c7a90
C::THIS = 0x7ffc1e7c7a80

I can't understand that i send &e to global_print and pb in global_print is equal to 0x7ffc1e7c7a90. And then i invode pb->print(), the this pointer in global_print is 0x7ffc1e7c7a80 which is equel to pc. It seems that the pb->print() convert class B to class C, but class B is the father class of class C, how dose it convert?

And although pb can get addres of C::print by virtual function, it's only a address that havn't enough information to konw that is need to convert class B to class C, so how does the program konw that need to convert class B to class C in the run time?

THANKS a lot! wish have a nice day!

梁立浩
  • 1
  • 1
  • 3
    all non-static member functions have an implicit parameter which is the object theyre being called on, thats where this comes from – Borgleader Apr 10 '21 at 14:55
  • but pb in global_print() is a pointor that it can point to any derive object, it means that pb need to convert to any type of derive class, but how dose pb konw which one it need to convert in the runtime? – 梁立浩 Apr 10 '21 at 15:08
  • The compiler does not convert a class (what would that ever mean?) It converts a pointer. Since the virtual function belongs to C, the compiler knows that this B pointer actually points to a base of C and not to a standalone B object. – n. m. could be an AI Apr 10 '21 at 15:14
  • i think the compiler doesn't know which derive object the pb point at actually in global_print(). so the class B convert to class C wouldn't happen in the compile time, it should happen in the program run time.but i don't konw how dose the program konw the class B should convert to class C? – 梁立浩 Apr 10 '21 at 15:24
  • Google "c++ adjustor thunk" to find relevant articles. [Example hit](https://en.wikipedia.org/wiki/Thunk#Object-oriented_programming) – Hans Passant Apr 10 '21 at 15:28
  • Yes it happens at run time of course. The program knows to convert a B pointer to a C pointer the same way it knows to call a C function using a B pointer. – n. m. could be an AI Apr 10 '21 at 15:31
  • thanks guy, you show me a way – 梁立浩 Apr 10 '21 at 15:32
  • the program konws to call a C function using a B pointer by virtual function, i think the virtual table is only store the address of function, without the class of function. so we can get the address of C function but can't get the class of C function – 梁立浩 Apr 10 '21 at 15:38
  • One question per stackoverflow.com question, please. You are asking multiple questions about how virtual functions work. – Sam Varshavchik Apr 10 '21 at 15:56
  • What a virtual function table stores, and whether it exists at all, is an implementation detail. In a typical implementation, the virtual function table stores not only the function address, but also some data and/or code needed to convert pointers (exactly what is required to convert from B to C). – n. m. could be an AI Apr 11 '21 at 12:28
  • thanks @n. 'pronouns' m., you figure out my problem, best wishes to you – 梁立浩 Apr 11 '21 at 14:12

0 Answers0