By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,407 Members | 1,057 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,407 IT Pros & Developers. It's quick & easy.

auto_ptr

P: n/a
alg
I am learning to use "auto_ptr" and found that the following 2 line would
not compile:

auto_ptr<Cat> pCat;
pCat = new Cat(6);

until I changed it to the one:

auto_ptr<Cat> pCat(new Cat(6));

Anf the error is:

"error C2679: binary '=' : no operator defined which takes a right-hand
operand of type 'class Cat *' (or there is no acceptable conversion)"

Could you please give me some reasons why such an error?

Thanks for your help!
Jul 19 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Ǽ

"alg" <al******@yahoo.com> wrote in message
news:85*********************@bgtnsc04-news.ops.worldnet.att.net...
I am learning to use "auto_ptr" and found that the following 2 line would
not compile:

auto_ptr<Cat> pCat;
pCat = new Cat(6);

until I changed it to the one:

auto_ptr<Cat> pCat(new Cat(6));

Anf the error is:

"error C2679: binary '=' : no operator defined which takes a right-hand
operand of type 'class Cat *' (or there is no acceptable conversion)"

Could you please give me some reasons why such an error?

Thanks for your help!


auto_ptr doesn't allow implicit conversion from plain pointer.
It'll work if you try this:

auto_ptr<Cat> pCat;
pCat = auto_ptr<Cat>(new Cat(6));

Jul 19 '05 #2

P: n/a

"alg" <al******@yahoo.com> wrote in message
news:85*********************@bgtnsc04-news.ops.worldnet.att.net...
| I am learning to use "auto_ptr" and found that the following 2 line would
| not compile:
|
| auto_ptr<Cat> pCat;
| pCat = new Cat(6);
|
| until I changed it to the one:
|
| auto_ptr<Cat> pCat(new Cat(6));
|
| Anf the error is:
|
| "error C2679: binary '=' : no operator defined which takes a right-hand
| operand of type 'class Cat *' (or there is no acceptable conversion)"
|
| Could you please give me some reasons why such an error?

The following...

# include <memory>
std::auto_ptr<Cat> pCat( new Cat( 6 ) );

....should work fine.

Did you include the correct header ?

Cheers.
Chris Val


Jul 19 '05 #3

P: n/a
alg wrote:
I am learning to use "auto_ptr" and found that the following 2 line would
not compile:

auto_ptr<Cat> pCat;
pCat = new Cat(6);

until I changed it to the one:

auto_ptr<Cat> pCat(new Cat(6));

Anf the error is:

"error C2679: binary '=' : no operator defined which takes a right-hand
operand of type 'class Cat *' (or there is no acceptable conversion)"

Could you please give me some reasons why such an error?
...


The compiler has already given you the reason. 'std::auto_ptr' cannot be
assigned from an ordinary pointer since there is no way to convert this
pointer to any of the types 'std::auto_ptr's assignment operators will
accept.

You can use either the 'std::auto_ptr's constructor or, if you really
need to change the store pointer value afterwards, 'std::auto_ptr's
method 'reset'.

--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP

Jul 19 '05 #4

P: n/a
"alg" <al******@yahoo.com> wrote in message news:<85*********************@bgtnsc04-news.ops.worldnet.att.net>...
I am learning to use "auto_ptr" and found that the following 2 line would
not compile:

auto_ptr<Cat> pCat;
pCat = new Cat(6);

until I changed it to the one:

auto_ptr<Cat> pCat(new Cat(6));


People have already given the correct reason (there is no implicit
conversion from T* to auto_ptr<T>); I will give you the reason as
there are some people here who would be glad to see it I think. I know
that a month ago (before reading Josuttis) I would have. So anyway:

Because auto_ptr is a smart pointer, it will take "ownership" of the
pointer. This is what it's made for, therefor it is usually a good
thing. However, sometimes it can be easy to give an auto_ptr ownership
when you don't want to or don't realize it.

You'll notice that the following also will (should) not compile:
auto_ptr<Cat> pCat = new Cat(6);
Note that this is different than the two examples you use above,
especially the first. A statement such as the above will call a
one-argument constructor, not the default constructor and then an
assignment. Thus the above call is *almost* the same as
auto_ptr<Cat> pCat(new Cat(6));
The only difference is that in the first example there is an implicit
conversion from Cat* to auto_ptr<Cat>, while the second example has an
explicit conversions.

Normally implicit conversions are well and good, for instance it's
very nice to be able to say
string s = "Hello world!";
which is an implicit conversion from const char* to string. As another
example,
double abs(double arg)
{ return (arg>0) ? arg : -arg; }

c = abs(14);
is also an implicit conversion from an integer (14) to a double. (For
the record, I don't know if that's the actual signature of a standard
version of abs, but we'll go with it at least.) It'd be kind of a pain
to have to write
c = abs(double(14));
instead. (Actually, 14.0 would be better there, but that would of
course not work with variables.) However, implicit conversions can be
a source of problems in certain cases, which comes up a lot with
auto_ptrs.

For instance, consider what would happen if you pass a smart pointer
to a function:
template<typename T>
void foo(auto_ptr<T> uhoh)
{ }
the argument uhoh takes posession of the passed object which is then
destroyed when the function exits. Meanwhile your client code
Cat *c = new Cat;
foo(c);
calls foo, perhaps not realzing that foo takes an auto_ptr, or not
realizing the semantics of auto_ptr, or you think you're calling a
different function, or whatever. In any case, a temporary
auto_ptr<Cat> is created that points to *c, it's passed to the
function which takes ownership of it in the form of uhoh, the function
goes out of scope, uhoh is destructed which deletes the Cat object,
and the function returns. You then go to try to use c some more
c->Purr(Cat::loudly);
but the Cat c points to is now deleted! (I'm not sure if auto_ptr sets
the pointer to null; a quick look at Josuttis seems to indicate it
doesn't, but I'm not sure.)

What is much better is for implicit conversions to be ruled out. The
way this is done is to specify the constructor as explicit, as in
explicit auto_ptr(T* ptr = 0);
(this is the actual relivant constructor according to Josuttis minus
the throw();). The explicit keyword gurantees that mistakes like the
above con't be made. It requires
auto_ptr<Cat> apc(new Cat(9));
Cat *c = new Cat(9);
foo(auto_ptr<Cat>(c)); // note the explicit cast
instead of
auto_ptr<Cat> apc = new Cat(9);
Cat *c = new Cat(9);
foo(c); // note the explicit cast

While from what I've seen it seems that most of the problems could
come from one-argument constructors being called implicitly, there are
I'm sure similar problems with assignment operators allowing
assignment of T* directly, so this is why it isn't allowed.
Jul 19 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.