Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why auto_ptr initialization using the assignment syntax is not allowed

I was reading through this book C++ standard library book

And here is the part i can not understand:

Note that class auto_ptr<> does not allow you to initialize an object with an ordinary pointer by using the assignment syntax.

std::auto_ptr<ClassA> ptr1(new ClassA); //ok
std::auto_ptr<ClassA> ptr2 = new ClassA; //error

I don't understand why it is not allowed. What kind of pitfalls they were trying to avoid by not allowing initialization with assignment syntax

like image 267
Vaska el gato Avatar asked Mar 22 '26 21:03

Vaska el gato


2 Answers

The fact that the assignment syntax cannot be used to initialize an auto_ptr from a raw pointer is a side effect of the constructor which takes a raw pointer being marked explicit. And the usual reason to mark a constructor as explicit is to prevent things like this:

void take_ownership(std::auto_ptr<ClassA> ptr) {
    // the pointer is deleted when this function ends
}

void foo() {
    ClassA obj;
    take_ownership(&obj); // oops, delete will be called on a pointer to
                          // an object which was not allocated with new
}

The call to the take_ownership function is an error there, because of the explicit classifier on the std::auto_ptr constructor. Instead, you have to deliberately construct an auto_ptr and pass that to the function.

void foo() {
    std::auto_ptr<ClassA> ptr(new ClassA);
    take_ownership(ptr); // okay
}

Of course this is not completely impervious to abuse (you can still pass a non-newed object to the constructor of auto_ptr), it is at least easier to spot when an abuse is taking place.

By the way, std::auto_ptr is deprecated. It is a very broken class (due to limitations in the language at the time it was introduced). Use std::unique_ptr instead.

like image 120
Benjamin Lindley Avatar answered Mar 25 '26 10:03

Benjamin Lindley


Here is how std::auto_ptr defined:

template< class T > class auto_ptr;
template<> class auto_ptr<void>;

Hence auto_ptr is a class type. Let's see its constructors:

explicit auto_ptr( X* p = 0 );
auto_ptr( auto_ptr& r );
template< class Y >
auto_ptr( auto_ptr<Y>& r );
template< class Y >
auto_ptr( auto_ptr_ref<Y> m );

Consider the first constructor. we can use a pointer to X type object as parameter to call this constructor:

std::auto_ptr<X> ptr1(new X); //ok

In the meanwhile, this first constructor is explicit, hence we cannot use a pointer to X type object implicitly to transform to auto_ptr<X>. In other words, we cannot initialize directly it via a pointer to X type object.

    std::auto_ptr<X> ptr1 = new X; //error; cannot implicitly transform
like image 40
chenzhongpu Avatar answered Mar 25 '26 12:03

chenzhongpu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!