Search This Blog

Sunday, September 9, 2012

Understanding Methods – A new Approch




Do you agree that a class member function cannot be called by without creating instance of that class???

If yes then think why these below lines of code is working


// ClassTest.cpp : Defines the entry point for the console application.//

#include "stdafx.h"
#include "iostream"

using namespace std;

class TestClass
{
public:

 int testFunc()
 {
  return 5;
 }

 void testFunc1()
 {
  cout << "testFunc1" << endl;
 }
};

int _tmain(int argc, _TCHAR* argv[])
{
 TestClass* pUninitialized = NULL;

 int i =  pUninitialized->testFunc();

 cout << i << endl;

 pUninitialized->testFunc1();

 return 0;
}


Here is the output

5
testFunc1
Press any key to continue . . .


Now you might wondering by observing the output. Let’s understand what is happening here
  1. First class member function does not occupy memory for each object. They get memory allocated once, and several objects call the same method. Here is the catch. Objects only gets memory allocated for their member variables not for member functions. But class member function can be called by only their object.

    Lets have a look on assembly code generated by visual studio 2010 compiler

    TestClass* pUninitialized = NULL;
    mov dword ptr [pUninitialized],0

    int i = pUninitialized->testFunc();
    // pushing "this" before function calling (NULL in our case)
    mov ecx,dword ptr [pUninitialized]
    // call to testFunc made by compiler
    call TestClass::testFunc (0D91203h)
    // getting value in var i returned from testFunc
    mov dword ptr [i],eax

    pUninitialized->testFunc1();
    // pushing "this" before function calling (NULL in our case)
    mov ecx,dword ptr [pUninitialized]
    // call to testFunc1 made by compiler
    call TestClass::testFunc1 (0D91168h)

  2. I added following code in main fucntion
    TestClass obj;

    int j = obj.testFunc();
    obj.testFunc1();

    Lets analyze its assembly code
    TestClass obj;
    lea ecx,[obj]
    // call to constructor
    call TestClass::TestClass (0D9124Eh)

    int j = obj.testFunc();
    // pushing "this" before function calling
    lea ecx,[obj]
    // call to testFunc made by compiler
    call TestClass::testFunc (0D91203h)
    mov dword ptr [j],eax
    obj.testFunc1();
    lea ecx,[obj]
    call TestClass::testFunc1 (0D91168h)

    It is clear that compiler makes the call to functions after pushing obj into stack. So function call can be made for valid instance or NULL instance.
  3. So now we understand that how it is possible to call member function without creating class instance as compiler insert code to call the function after pushing "this" in stack.


No comments:

Post a Comment