简体   繁体   中英

function returning this pointer in c++

1st code:

#include <iostream>
using namespace std;
class demo
{
  int a;
public:
  demo():a(9){}
  demo& fun()//return type isdemo&
  {
    return *this;
  }
};

int main()
{
  demo obj;
  obj.fun();
  return 0;
}

2nd code:

#include <iostream>
using namespace std;
class demo
{
  int a;
public:
  demo():a(9){}
  demo fun()//return type is demo
  {
    return *this;
  }
};

int main()
{
  demo obj;
  obj.fun();
  return 0;
}

what is the difference between these two codes as both are working in gcc?i am new here so forgive me if my way of asking is wrong.

demo & fun() returns a reference to the current object. demo fun() returns a new object, made by copying the current object.

Apart from what @Erik said about the return type, a little excursus on the this -pointer:
The following is equivalent:

struct my_struct{
  my_struct* get_this() const { return this; }
};

my_struct obj;
my_struct* obj_this = ob.get_this();

std::cout << std::boolalpha; // to display true/false instead of 1/0
std::cout << "&obj == obj_this = " << &obj == obj_this << "\n";

The this pointer is just the pointer to that object, you can think of it as a hidden parameter. It's more understandable in the C way:

typedef struct my_struct{
  int data;
  // little fidgeting to simulate member functions in c
  typedef void (*my_struct_funcptr)(struct my_struct*,int);
  my_struct_funcptr func;
}my_struct;
// C++ does something similar to pass the this-pointer of the object
void my_struct_func(my_struct* this, int n){
  this->data += n;
}

my_struct obj;
obj.data = 55;
// see comment in struct
obj.func = &my_struct_func;
obj.func(&obj, 15);
//       ^^^^ - the compiler automatically does this for you in C++
std::cout << obj.data; // displays 70

Both are valid but are different. In the first case demo& fun() a reference to the same object is returned, in the second case a new object is created. While both are the same, the semantics differ, run this example:

#include <iostream>
struct test {
  int x;
  test() : x() {}
  test& foo() { return *this; }
  test bar() { return *this; }
  void set( int value ) { x = value; }
};
int main() {
  test t;
  t.foo().set( 10 );             // modifies t
  t.bar().set( 5 );              // modifies a copy of t
  std::cout << t.x << std::endl; // prints 10
}

Consider your function.

demo fun(){return *this;}

Here you are returning by value so one temporary object will be created which will be destroyed, once you assign the return value of fun to some other object.

While in case when you pass the reference, no object will be created newly, but it will pass actual object and even after assigning function return value object will not destroy till main object(used inside fun, in ur case its the object calling the function) won't go out of scope.

The concept you are trying to understand can be explained in more detail with other example. consider function that is taking object as argument and returning object as argument.(also consider we have object that contains a pointer, we will assign value to pointer by first allocating memory to pointer and a destructor, which will free memory hold by pointer of object). Now when you return object as pass by value, temporary object will be created, that will have exact copy of main object(and temporary object's pointer will also point to same address or you can say holds the same address). Now inside main(), you assign/initialize any object with return value(object) of function. But when your temp object will be destroyed after assigning value, it will also free the memory because of destructor and when you try to fetch the same address value through assigned object(inside main() ) you will get error as that memory has been already freed.

But if you would have return value using reference, object returned by object won't destroy as main obj(inside function or through which we have called the function) is in scope and your pointer won't loose its memory. Making possible for assigned object to fetch address value through its pointer and avoid undesirable result.

In code 1 demo obj creates a fresh copy of demo. obj is initialised using demo's default constructor 'demo():a(9){}'. obj.fun() returns a reference to (already existing) obj .

In code 2 obj.fun() creates a new demo type object using demo's copy constructor (in your case it is compiler generated) and returns that copy to the caller.

Both code are valid.

  1. 1st code fun() is returning a reference to current object
  2. 2nd code fun() is returning the copy (by value) of the object
  3. For 1st case, If you decide to return by value then prefer to return a const reference; ie const demo& fun(); and later you can copy it if needed. Simply returning reference makes the object modifiable, which may accidently edit the content without intent
  4. For 2nd case, Do NOT return the object by value, because it can create unnecessary temporary copy which will effect the memory/performance of your code

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM