Passing auto_ptr<T> by non-const reference.

Hi Everyone

Could someone please let me know what the C++ standard says about passing auto_ptr's by non-const reference.
Does it or does it not transfer ownership of the object to which it points??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Employee
{

};

void foo(std::auto_ptr<Employee>& roEmp)
{
   // Does the Employee object gets deleted when we exit foo() ??
}

int main()
{
   std::auto_ptr<Employee> poEmp(new Employee);

   foo(poEmp);

   return 0;

} // or does the Employee object gets deleted here.. when we exit main??



From http://www.cplusplus.com/reference/std/memory/auto_ptr/auto_ptr/ :

1
2
template<class Y>
  auto_ptr (auto_ptr<Y>& a)
- Copy constructor -
Ownership is taken from it, therefore, a releases it.
When the types held by the origin and destination auto_ptrs are different, an implicit conversion must be available between their pointers.
Then could you please explain the output of the following code (compiled using gcc 3.4.6)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
using std::cout;
using std::endl;
using std::auto_ptr;

class Employee
{
public:
   Employee()
   {
      cout << "Constructing Employee object" << endl;
   };

   ~Employee()
   {
      cout << "Destructing Employee object" << endl;
   };

};

void foo(auto_ptr<Employee>& roEmp)
{
   cout << "Inside function foo()" << endl;
}

int main()
{
   auto_ptr<Employee> poEmp(new Employee);
   foo(poEmp);
   cout << "After function foo.. leaving main now" << endl;
   return 0;
}


Output is:

Constructing Employee object
Inside function foo()
After function foo.. leaving main now
Destructing Employee object


It looks as though in this case auto_ptr did not transfer ownership; otherwise "Destructing Employee object" should have output before "After function foo.. leaving main now"

You are passing by reference, which means that roEmp (function parameter) is the same object as poEmp (argument)
I thought you was asking when passing by value
Hi Bazzy

Yes "roEmp" & "poEmp" both point to the same underlying Employee object. But only one of these: "roEmp" or "poEmp" should own that Employee object.

If transfer of ownership does happen, then this would mean that when "roEmp" gets destroyed, it should also call delete for the Employee object.

Since "roEmp" is a local variable inside foo(), it gets destroyed when foo() returns. So it must call delete on Employee if it has ownership of that object.

But it seems this is not the case here.

All i want to know is that "Does the C++ standard say that passing auto_ptr's by non-const reference does not transfer ownership"??
and "is passing auto_ptr's by non-const reference portable"??

Regards
Rajat
roEmp isn't a variable, is a reference so it wouldn't get destroyed.
In the foo() function of the code (above) compiled using gcc 3.4.6, it receives a reference to Employee object. Therefore the foo function works on the same Employee object that the calling function (inside main() ) passed to it. Since there is no assignment of auto_ptr object from one to the other, you are not testing the ownership.

The following modified code does involved the ownership issue (generating different output):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
using std::cout;
using std::endl;
using std::auto_ptr;

class Employee
{
public:
   Employee()
   {
      cout << "Constructing Employee object" << endl;
   };

   ~Employee()
   {
      cout << "Destructing Employee object" << endl;
   };

};

void foo(auto_ptr<Employee> insideEmp)//NOTE: pass-by-value
{
   cout << "Inside function foo()" << endl;
} // Emp object destroyed here

int main()
{
   auto_ptr<Employee> outEmp(new Employee);
   
   foo(outEmp); // outEmp now points to NULL; insideEmp points to   
                // the Emp obj and get destroyed before exiting foo()

   cout << "After function foo.. leaving main now" << endl;
   return 0;
}


The tricky thing about auto_ptr in terms of ownership is as follows:
1
2
3
auto_ptr<Employee> p1(new Employee);
auto_ptr<Employee> p2(p1); //p2 now points to Employee object, p1 points to NULL
p1 = p2; //p1 now points to Employee object, p2 points to NULL 


Different from the tr1::shared_ptr, an Employ object managed by auto_ptr can never have more than one auto_ptr pointing to them at one time.
Last edited on
Topic archived. No new replies allowed.