Problems when using this in C++ multiple inheritance - parent class calls subclass function pointer

In the case of multiple inheritance, the addresses pointed to by this in the functions of the parent classes are different.
Look at the following example:

#include <iostream>
using namespace std;

class A {
    
    
public:
    void printA() {
    
     cout << this << endl; }
    int a;
};

class B {
    
    
public:
    void printB() {
    
     cout << this << endl; }
    int b;
};

class C : public A, public B {
    
    
public:
    C() {
    
    }
    void print() {
    
    
        printA();
        printB();
        cout << this << endl;
    }
    int c;
};

int main()
{
    
    
    C *c = new C;
    c->print();
    return 0;
}

The printing result is:
Insert image description here
this in class A function and this in class C function point to the same address, while this in class B function points to an address offset by 4 bytes.
Insert image description here
For information on the storage structure of multiple inheritance, please refer to this article: Understanding C++ principles from an assembly perspective - class storage structures and function calls

Problems

It may crash when calling a subclass function from within a parent class function. Such as the following routine:

#include <iostream>
using namespace std;

class Base {
    
    };

class A : public Base {
    
    
    int a;
};

class B {
    
    
public:
    void exec() {
    
    
        if (func != NULL)
            (this->*func)();
    }
    
    int b;
    void (B::*func)() {
    
     NULL };

};

class C : public A, public B {
    
    
public:
    C() {
    
    
        func = static_cast<void (B::*)()>(&C::print);
    }

    void print() {
    
    
        if (data != NULL) cout << *data << endl;
    }

    int *data {
    
     NULL };
};

int main() {
    
    
    int data = 10;
    C *c = new C;
    c->data = &data;
    c->exec(c);

    return 0;
}

It will crash after running because (this->*func)(); in exec, this does not point to this in class C, so a wild pointer will be accessed, causing the program to crash.
A modification should be made to exec here:

void exec(void *realSelf) {
    
    
	if (func != NULL) ((B*)realSelf->*func)();
}

When using, pass in the first address of the C object.

Guess you like

Origin blog.csdn.net/weixin_45001971/article/details/130964341
Recommended