this
adjustment can happen only in classes that use multiple-inheritance. Here's a program that illustrates this:
#include <iostream>
using namespace std;
struct A {
int n;
void af() { cout << "this=" << this << endl; }
};
struct B {
int m;
void bf() { cout << "this=" << this << endl; }
};
struct C : A,B {
};
int main(int argc, char** argv) {
C* c = NULL;
c->af();
c->bf();
return 0;
}
When I run this program I get this output:
this=0
this=0x4
That is: your assert this != nullptr
will not catch the invocation of c->bf()
where c is nullptr
because the this
of the B
sub-object inside the C
object is shifted by four bytes (due to the A
sub-object).
Let's try to illustrate the layout of a C
object:
0: | n |
4: | m |
the numbers on the left-hand-side are offsets from the object's beginning. So, at offset 0
we have the A
sub-object (with its data member n
). at offset 4
we have the B
sub-objects (with its data member m
).
The this
of the entire object, as well as the this
of the A
sub-object both point at offset 0. However, when we want to refer to the B
sub-object (when invoking a method defined by B
) the this
value need to be adjusted such that it points at the beginning of the B
sub-object. Hence the +4.