tags:

views:

303

answers:

3

The size of a class with no data members is returned as 1 byte, even though there is an implicit 'this' pointer declared. Shouldn't the size returned be 4 bytes(on a 32 bit machine)? I came across articles which indicated that 'this' pointer is not counted for calculating the size of the object. But I am unable to understand the reason for this. Also, if any member function is declared virtual, the size of the class is now returned as 4 bytes. This means that the vptr is counted for calculating the size of the object. Why is the vptr considered and 'this' pointer ignored for calculating the size of object?

+2  A: 

The this pointer is not a member of the class. It's just a construct that is used in methods belonging to the class to refer to the current instance.

If you have a class like this:

class IntPair
{
public:
  IntPair(int a, int b) : _a(a), _b(b) { }

  int sum() const { return _a + _b; }

public:
  int _a;
  int _b;
};

This class only needs space for two instances of int for each instance. Once you've created an instance and are running the sum() method, that method is called with a pointer to the instance, but that pointer always comes from somewhere else, it isn't stored in the object instance.

For example:

IntPair *fib12 = new IntPair(89, 144);

cout << fib12->sum();

Notice how the variable that becomes the this pointer is stored outside the object, in the scope that created it.

You could, in fact, always transform a method like the one above into:

static int sum2(const IntPair* instance)
{
  return instance->_a + instance->_b;
}

If the above is defined inside the class (so it can access the private members), there's no difference. In fact, this is how methods are implemented behind the scene; the this pointer is just a hidden argument to all member methods.

The call would become:

IntPair* fib12 = new IntPair(89, 144);

cout << IntPair::sum2(fib12);
unwind
+2  A: 

'this' is not stored as a data member in the class, it's just a 'pointer' to the instance of the class. Consider it as a 'hidden argument' passed to the method. In fact, on Win32 systems it is often passed in the ecx register (not eax as I thought initially).

As soon as you have 1 or more virtual methods, your application needs a way to store the pointers to the virtual methods. This is called the vtable, which is identical for all instances of the same class. Since you need to know at run-time which 'explicit' method to call for which 'virtual method' a pointer to the vtable is stored in the class instance. Therefore the vtable-pointer (or vptr) needs 4 bytes (or 8 bytes on a 64-bit system).

Patrick
I thought it was passed in `ecx`.
Blindy
Oops, yes you're right.eax is used for the return value.(I edited the post)
Patrick
+2  A: 

The this pointer is not stored inside the object. There's no need to do that. You already have a pointer or an object to invoke the functions on. As for the size of 1, the C++ standard reqires that distict objects have distinct addresses.

sellibitze