c++ this pointer clarification

Discussion in 'Programmer's Corner' started by TheFox, Oct 19, 2011.

  1. TheFox

    Thread Starter Active Member

    Apr 29, 2009
    66
    5
    So, I was wondering, would it be better to use this, as apposed to just using them as is?
    e.g.,

    Code ( (Unknown Language)):
    1. class clsExampleClass
    2. {
    3.      int AddTwoNumbers(int NumOne, int NumTwo)
    4.      {
    5.           return (NumOne + NumTwo);
    6.      }
    7.  
    8. public:
    9.      int TheSumOfTwoNumbers(int NumOne, int NumTwo)
    10.      {
    11.           return this->AddTwoNumbers(NumOne,NumTwo)
    12.      }
    13. };
    OR, this

    Code ( (Unknown Language)):
    1. class clsExampleClass
    2. {
    3.      int AddTwoNumbers(int NumOne, int NumTwo)
    4.      {
    5.           return (NumOne + NumTwo);
    6.      }
    7.  
    8. public:
    9.      int TheSumOfTwoNumbers(int NumOne, int NumTwo)
    10.      {
    11.           return AddTwoNumbers(NumOne,NumTwo)
    12.      }
    13. };
     
  2. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    In C++ "this" keyword refers to a pointer. When you declare a function in C++,the compiler create exactly the function you ask for, but if you create a member function i.e.. a function that belongs to a class, the compiler will modify the function a bit .It will add a secrete parameter to your member function and that parameter is the pointer to the class itself and known as “this” and if you want to use that in your code you use it by using the "this" keyword.

    Your both the codes are equivalent, you don't need to use the "this" keyword, when you are inside a class, compilers secretly use the "this" pointer. I have seen people using this keyword everywhere in their code, which actually does nothing to their code. Occasionally you will actually need "this" keyword.

    In case of static member functions ,the compiler will not add the "this" pointer to the function.

    Good Luck
     
    TheFox likes this.
  3. TheFox

    Thread Starter Active Member

    Apr 29, 2009
    66
    5
    Thanks. I should have guessed that the compiler would do that automatically. I don't know that much about static; I guess I know what I'll be reading about tomorrow.

    When I first learned about "this" pointer, I tried to do something like

    Code ( (Unknown Language)):
    1. class FailureExample
    2. {
    3. public:
    4.      ~FailureExample()
    5.      {
    6.           delete this;
    7.      }
    8. };
    Obviously, My compiler, and OS disapproved highly.
     
    Last edited: Oct 20, 2011
  4. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    When we create some object in system's memory heap i.e.. to allocate memory dynamically at runtime we use the "new" operator and to release the memory we use "delete" operator. Another way to create an object is to create it in application's stack space, if you create something in stack you don’t need to release it, compiler will handle it for you. For example

    Code ( (Unknown Language)):
    1.  
    2. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]<iostream>[/COLOR][/SIZE]
    3. [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]namespace[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] std;[/SIZE]
    4. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] diode[/SIZE]
    5. [SIZE=2]{[/SIZE]
    6. [SIZE=2]};[/SIZE]
    7. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] main()[/SIZE]
    8. [SIZE=2]{[/SIZE]
    9. [SIZE=2]diode d_stack;[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]//allocate memory in stack[/COLOR][/SIZE]
    10. [/COLOR][/SIZE][SIZE=2]diode *d_heap = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] diode;[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// allocate memory in heap.[/COLOR][/SIZE]
    11. [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]delete[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] d_heap;[/SIZE][SIZE=2][COLOR=#008000][SIZE=2][COLOR=#008000]// release the memory.[/COLOR][/SIZE]
    12. [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
    13. [SIZE=2]}[/SIZE]
    14.  
    Now the "this" pointer is a pointer that refers to any particular object. In the above program we created two diode object one in application’s stack space "d_stack" and another in system heap "d_heap".Now the "delete" can only be used if the object is dynamically created using new operator ,so if you call delete in destructor of "d_stack" that is not correct as it was not allocated on heap rather it was created in stack.

    For "d_heap" stuff it will compile and will not give any error.Like

    Code ( (Unknown Language)):
    1.  
    2. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]<iostream>[/COLOR][/SIZE]
    3. [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]namespace[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] std;[/SIZE]
    4. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] diode[/SIZE]
    5. [SIZE=2]{[/SIZE]
    6. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]:[/SIZE]
    7. [SIZE=2]diode()[/SIZE]
    8. [SIZE=2]{[/SIZE]
    9. [SIZE=2]}[/SIZE]
    10. [SIZE=2]~diode()[/SIZE]
    11. [SIZE=2]{[/SIZE]
    12. [SIZE=2]cout<<[/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"Destructor call\n"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];[/SIZE]
    13. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]delete [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]this[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];[/SIZE]
    14. [SIZE=2]}[/SIZE]
    15. [SIZE=2]};[/SIZE]
    16. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] main()[/SIZE]
    17. [SIZE=2]{[/SIZE]
    18. [SIZE=2]diode *d_heap = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] diode;[/SIZE]
    19. [SIZE=2]system([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"pause"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]);[/SIZE]
    20. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
    21. [SIZE=2]}[/SIZE]
    22.  
    But you should not do it as first of all you will not able to create object of this class in stack space, and destructor are not used to destroy the object itself rather its used to destroy the data member of the class(object) as destructor is a member function and when you are inside it, the object(class) is still needed you can't destroy it.After you exit from destructor compilers do some job to clean things, if you destroy it before, you may have memory leak. Anyway C/C++ sets some rules for us programmers you follow them you will have less trouble ,of course you can bypass these rules that’s the power of the language and it's the reason that C/C++ is the industries most powerful and favored language.

    A static member function is created once in static space of application's memory space like static data members, it is bounded to a particular class rather to the objects of that class, it's the reason that you can use a static function without an instance of the class just using the scope-resolution operator like this
    Code ( (Unknown Language)):
    1.  
    2.  
    3. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] Me {[/SIZE]
    4. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]:[/SIZE]
    5. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]static [/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]void[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] f(){};[/SIZE]
    6. [SIZE=2]};[/SIZE]
    7. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] main() {[/SIZE]
    8. [SIZE=2]Me::f();[/SIZE]
    9. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
    10. [SIZE=2]}[/SIZE]
    11.  
    In member functions the address of the current object is quietly passed as "this" pointer but in case of static member function "this" pointer is not pass and this is the reason that you can’t access data members inside static function. Only static data members can be access inside static function.

    You could find a lot more over internet, it’s too big to explain these things in post.

    Good Luck
     
    Last edited: Oct 20, 2011
    TheFox likes this.
  5. TheFox

    Thread Starter Active Member

    Apr 29, 2009
    66
    5
    Thanks, this had been very insightful, and lead me in the right way, as to what to look for in the internet.
    EDIT: I was told that you should always use the constructor, even if you don't write one, just be cause it was "better". Is there anything other good reason than good style?
     
    Last edited: Oct 20, 2011
  6. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    A constructor guarantees initialization .You can't initialize data members while defining them. For example
    Code ( (Unknown Language)):
    1.  
    2. class Me
    3. {
    4.  private:
    5.       int i = 0;//Error you can't do this...
    6.  public:
    7.       int y;//proper way to declare.
    8.       void myfunc()
    9.      {
    10.       y = 0;//initialize
    11.      }
    12. };
    13. int main()
    14. {
    15.  Me me;
    16.  cout<<me.y;//error 'y' is not initialized
    17.  me.myfunc();//initializing 'y'
    18.  cout<<me.y//Now its ok to use 'y'
    19.  return 0;
    20. }
    21.  
    In above code if you create an instance of "Me" class and try to use data member "y" you will get an error as its not initialized unless you call myfunc() which initialize "y".So to avoid this problem C++ use constructor, compiler automatically calls it at the time of object creation before any other operation, inside constructor we initialize our data members and which guarantees initialization.

    Code ( (Unknown Language)):
    1.  
    2. class Me
    3. {
    4.  private:
    5.       int i = 0;//Error you can't do this...
    6.  public:
    7.       int y;//proper way to declare.
    8.       Me()
    9.      {
    10.       y = 0;
    11.      }
    12. };
    13. int main()
    14. {
    15.  Me me;//constructor is called at this point
    16.  cout<<me.y;//ok
    17.  return 0;
    18. }
    19.  
    If your class have no constructor then compiler will create a default constructor as a safety net ,but that default constructor will not guarantee proper initialization of the object so you should always define one your self and initialize your data members inside it.

    EDIT:
    If you are asking about writing the default constructor ,then it's not needed as compiler will create it for you .For example both the code are equivalent

    Code ( (Unknown Language)):
    1.  
    2. class Me
    3. {
    4.  public:
    5.  int i;
    6.  Me()
    7.  {
    8.  }
    9. };
    10.  
    And
    Code ( (Unknown Language)):
    1.  
    2. class Me
    3. {
    4. public:
    5.  int i;
    6. };
    7.  
    But you can see the data member "i" will be not initialized and you can run into trouble.

    You are always welcome

    Good Luck
     
    Last edited: Oct 20, 2011
  7. TheFox

    Thread Starter Active Member

    Apr 29, 2009
    66
    5
    I could be wrong, what what I learned was:

    Code ( (Unknown Language)):
    1. class Greeting
    2. {
    3. public:
    4.      int Integer;
    5. };
    6.  
    7. int main()
    8. {
    9.      Greeting * Hello = new Greeting();
    10.      delete Hello;
    11.      return 0;
    12. }
    That you should have the () when you create the class to call the constructor. Otherwise, you don't use the constructor. But if you don't write a constructor, is still it better in anyway to do it that way?
     
  8. debjit625

    Well-Known Member

    Apr 17, 2010
    790
    186
    No their is nothing like that,when you create an object(an instance) of a class ,constructor will always be called no matters if you use parentheses "()" or not.
    For example check this code...
    Code ( (Unknown Language)):
    1.  
    2. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]<iostream>[/COLOR][/SIZE]
    3. [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]namespace[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] std;[/SIZE]
    4. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] X[/SIZE]
    5. [SIZE=2]{[/SIZE]
    6. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]:[/SIZE]
    7. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] integer;[/SIZE]
    8. [SIZE=2]X()[/SIZE]
    9. [SIZE=2]{[/SIZE]
    10. [SIZE=2]cout<<[/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"X constructor\n"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2];[/SIZE]
    11. [SIZE=2]}[/SIZE]
    12. [SIZE=2]};[/SIZE]
    13. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] main()[/SIZE]
    14. [SIZE=2]{[/SIZE]
    15. [SIZE=2]X * a = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] X;[/SIZE]
    16. [SIZE=2]a->integer = 0;[/SIZE]
    17. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]delete[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] a;[/SIZE]
    18. [SIZE=2]X * b = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] X();[/SIZE]
    19. [SIZE=2]b->integer = 0;[/SIZE]
    20. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]delete[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] b;[/SIZE]
    21.  
    22. [SIZE=2]system([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"pause"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]);[/SIZE]
    23. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
    24. [SIZE=2]}[/SIZE]
    25.  
    You will see two times the "X constructor" as we created two objects "a" and "b","a" is without parentheses "()".

    Parentheses are only used if you have some arguments to pass to the constructor like this
    Code ( (Unknown Language)):
    1.  
    2. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]#include[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]<iostream>[/COLOR][/SIZE]
    3. [/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]using[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]namespace[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] std;[/SIZE]
    4. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]class[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] X[/SIZE]
    5. [SIZE=2]{[/SIZE]
    6. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]public[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]:[/SIZE]
    7. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] integer;[/SIZE]
    8. [SIZE=2]X([/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] i)[/SIZE]
    9. [SIZE=2]{[/SIZE]
    10. [SIZE=2]integer = i;[/SIZE]
    11. [SIZE=2]cout<<[/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"X constructor and value of integer is "[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]<<integer<<endl;[/SIZE]
    12. [SIZE=2]}[/SIZE]
    13. [SIZE=2]};[/SIZE]
    14. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]int[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] main()[/SIZE]
    15. [SIZE=2]{[/SIZE]
    16. [SIZE=2]X * a = [/SIZE][SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]new[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] X(100);[/SIZE]
    17. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]delete[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] a;[/SIZE]
    18. [SIZE=2]system([/SIZE][SIZE=2][COLOR=#a31515][SIZE=2][COLOR=#a31515]"pause"[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]);[/SIZE]
    19. [SIZE=2][COLOR=#0000ff][SIZE=2][COLOR=#0000ff]return[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] 0;[/SIZE]
    20. [SIZE=2]}[/SIZE]
    21.  
    This will never happen as compiler will always call a constructor.If the compiler can't find one then it will create a default constructor.

    Good Luck
     
    TheFox likes this.
  9. TheFox

    Thread Starter Active Member

    Apr 29, 2009
    66
    5
    Thank you very much, for all your help. I was taught wrong. I was told that unless you put the (), it wouldn't use the constructor.
     
Loading...