tags:

views:

92

answers:

5

I am trying to understand functions returning a reference. For that I have written a simple program:

#include<iostream>
using namespace std;

class test
{
   int i;
   friend test& func();

public:
   test(int j){i=j;}
   void show(){cout<<i<<endl;}
};

test& func()
{
   test temp(10);
   return temp; //// Address of temp=0xbfcb2874
}

int main()
{
   test obj1(50); // Address of obj1=0xbfcb28a0
   func()=obj1; <= Problem:The address of obj1 is not changing
   obj1.show(); // // Address of obj1=0xbfcb28a0
   return 0;
}

I ran the program using gdb and observed that the address of obj1 still remains same, but I expect it to get changed to 0xbfcb2874. I am not clear with the concept. Please help.

+3  A: 

Returning a reference to a stack variable is undefined behavior. But if you returned an reference to an static field (for example), that line would set the static field's value to be equal to obj1's value. It would not change the address of obj1:

class test
{
    int i;
    friend test& func();
public:
   static test staticField;  
   test(int j){i=j;}
   void show(){cout<<i<<endl;}
};

test test::staticField(10); 

test& func()
{
    return test::staticField;
}

int main()
{
   test obj1(50); // Address of obj1=0xbfcb28a0
   cout << "Before: " << endl;
   cout << "field value: ";
   test::staticField.show();
   cout << "field addr: " << &test::staticField << endl;

   cout << "obj1 value: ";
   obj1.show();
   cout << "obj1 addr: " << &obj1 << endl;

   func()=obj1;

   cout << "After: " << endl;
   cout << "field value: ";
   test::staticField.show();
   cout << "field addr: " << &test::staticField << endl;

   cout << "obj1 value: ";
   obj1.show();
   cout << "obj1 addr: " << &obj1 << endl;
   return 0;
}
Matthew Flaschen
+4  A: 

There are several problems in your code:

(1) That is not how you want to return a reference. temp(10) is an automatic (i.e. resides in stack) variable and will be destroyed once your program goes out of scope of the test function. A better way to show this would be to return a reference to a variable passed (e.g. for chaining of calls):

Test& func(Test& some_param) {
  // Do something with some_param...

  // Return it as a reference.
  return some_param;
}

(2) You are assigning the value of obj1 to func(), while what you want would be to assign the return value of func() to a variable. Try this:

Test obj1(50);
Test& obj2 = func(obj1);  // Address of obj2 should now be the same as obj1.

(3) func() need not be a friend of Test. In fact, it should not. A friend class/functions allow the class/functions to access private members of Test. That is not what you want to do too often.

Chris Henry
Chris, for point (3), i agree with you. The func() need not to be declared as friend.Regarding (1), i have tried the same thing by making temp global but the end result remains same.
Ashish
See point (2). That is the reason why your result is the same. You should be assigning the return value to a reference variable, i.e. Temp
Chris Henry
Ashish
A: 

The address of obj1 will not change in that case - you're not assigning anything to it, you are assigning obj1 to the result of a function. You can't change the address of a stack variable anyway.

You should be getting all kinds of warnings from your compiler about returning / assigning references to temporary objects. You might be better starting with some kind of C++ book or tutorial...

Peter
Peter thanks for the reply.You are right about the warnings from compiler.I have also executed the same program by making temp global and changing func()=obj1; to obj1=func(); In this case also the address of obj1 is not changing but the value of obj1.i got changed. Am i doing the right thing?
Ashish
+2  A: 

I don't see how the address of any variable can be made to change unless it goes out of scope and is recreated in a different scope/iteration ...in which case, it is a different variable altogether.

Vulcan Eager
A: 

Really, what you should be doing is returning an object and let the compiler perform Return Value Optimization for you:

test func()
{
   test temp(10);
   return temp; 
}

int main()
{
   test obj1(50);
   obj1 = func();
   //obj1.value == 10
   return 0;
}
Igor Zevaka