Alok
Alok

Reputation: 2035

how to call a function when auto_ptr is a parameter of it!

#include <iostream>
#include <memory>

class test
{
     private:
         int x , y;
     public:
         test(int a , int b):x(a),y(b){}
         void fun()
         {
            std::cout<< x<<" "<<y<<" "<<std::endl;
         }
};

void show(std::auto_ptr<test> t1)
{
    t1->fun();
}

int main()
{

    show(new test(3,4));

}

I am getting a compilation error , please tell me what's wrong in this code?Thanks in advance.

Upvotes: 2

Views: 841

Answers (2)

Loki Astari
Loki Astari

Reputation: 264411

James explained how to resolve the problem.

But the reason auto_ptr was designed so that you can not do this:

show(new test(3,4));

Is because this is a bad idea.
Even this (if it were allowed):

show(std::auto_ptr<test>(new test(3,4)));

Would be a bad idea.
So you ask why.

Well in the normal situation not a big deal.
Bu what happens when you have a function that takes more than one parameter.

show2(std::auto_ptr<test>(new test(3,4)), SomeObject());

Now the standard gurantees that all parameters will be fully evaluated before the call (even the construction of the auto_ptr). But it does not guarantee the evaluation order nor that the evaluation will not be interleaved.

Thus it is possible for this evaluation:

  // Phsedu code for parameter evaluation
  test*                      tmp1 = new test(3,4);
  SomeObject const&          tmp2 = SomeObject();
  std::auto_ptr<test> const& tmp3(tmp1);
call(tmp3, tmp1)

This order is bad. Because if the constructor of SomeObject throws an exception you will leak tmp1 as it has not yet been assigned to the std::auto_ptr.

This is why we auto_ptr was designed so that you have to give it a named variable.

std::auto_ptr<test>  tmp3(new test(3,4));
SomeObject           tmp1;
call(tmp3, tmp1)

Now if SomObject constructor throws the test object will be tidied up.

Upvotes: 0

James McNellis
James McNellis

Reputation: 355069

Whenever you dynamically allocate an object, you should create a named smart pointer that immediately takes ownership of the object, then use that named smart pointer. For example,

std::auto_ptr<test> ptr(new test(3, 4));
show(ptr);

You cannot pass new test(3, 4) directly to the function because std::auto_ptr objects must be explicitly constructed; it would be quite unexpected if a smart pointer took ownership of an object implicitly.

That said, this is rather unusual anyway because when you call show(), the auto_ptr is copied and when auto_ptr is "copied," the original loses ownership and the copy gains ownership (so, after show() is called, you will find that ptr no longer has ownership of the object.

Upvotes: 3

Related Questions