smart_ptr question

T

toton

Hi,
I am using some smart_ptr (from Axter) in a STL vector. However I
need a custom deleter other than destructor (In my case a free member
function, which exists due to Historic reason only, do the cleanup and
commit suicide) . This smart_ptr is like STL auto_ptr (Single owner,
non-shared, copyable ). Can anyone point out whether it supports a
custom deleter.
1) STL auto_ptr doesn't have a custom deleter other than destructor.
2) Boost scoped_ptr can't be used with STL container (non copyable),
and do not have a custom deleter.
3) Boost shared_ptr has a custom deleter but it is shared, not owned.

Any reference is helpful.

Thanks
abir
 
Z

Zara

Hi,
I am using some smart_ptr (from Axter) in a STL vector. However I
need a custom deleter other than destructor (In my case a free member
function, which exists due to Historic reason only, do the cleanup and
commit suicide) . This smart_ptr is like STL auto_ptr (Single owner,
non-shared, copyable ). Can anyone point out whether it supports a
custom deleter.
1) STL auto_ptr doesn't have a custom deleter other than destructor.
2) Boost scoped_ptr can't be used with STL container (non copyable),
and do not have a custom deleter.
3) Boost shared_ptr has a custom deleter but it is shared, not owned.

Any reference is helpful.

Thanks
abir

If you want to use the pointer with an STL container, it must be
shared, to have the correct copy semantics. So, you must go with
boost::shared_ptr ort tr1::shared_ptr

Regards,
Zara
 
T

toton

Zara said:
If you want to use the pointer with an STL container, it must be
shared, to have the correct copy semantics. So, you must go with
boost::shared_ptr ort tr1::shared_ptr
Not sure, why it have to be shared. Only thing I look for that the
pointer owns the object, and pointer itself is copy constructable. If I
am not wrong, shared_ptr is a reference counted version, and deletes
the object only when all of the references gets out of scope. Thus one
or more container can "own" the object.
So the container "owns" the objects but stores the object pointers. And
thus container gets deleted, object should get deleted. Except it calls
destructor (i.e delete ) on the object, while I need to call free on it
(and that is only due to some old codes which are written with free,
not with destructor). shared_ptr can do all the jobs no doubt, however
it have more flexibility than what I need.
Anyway , I find it using axter policy based smart_ptr, There all I do
is write a simple policy which do call free rather than delete.
struct allocator_free_policy{
template<typename T_obj>
static inline T_obj* allocate(const T_obj* ptr){
if (ptr) return new T_obj(*ptr);///allocating by new.
return NULL;
}
template<typename T_obj>
static inline void deallocate(T_obj* ptr){
ptr->free();///allocating by free.
//delete ptr;
}
};
Thanks
 
Z

Zara

Not sure, why it have to be shared. Only thing I look for that the
pointer owns the object, and pointer itself is copy constructable. If I
am not wrong, shared_ptr is a reference counted version, and deletes
the object only when all of the references gets out of scope. Thus one
or more container can "own" the object.

It must be shared. Never mind the underlying details or the name,
Axter pointer must be shared if it may be used with STdLib containers
And Axter pointer admits the use os different policies pof allocation
and deletion, so there should be no problem with it, AFAIK.

Anyway , I find it using axter policy based smart_ptr, There all I do
is write a simple policy which do call free rather than delete.
struct allocator_free_policy{
template<typename T_obj>
static inline T_obj* allocate(const T_obj* ptr){
if (ptr) return new T_obj(*ptr);///allocating by new.
return NULL;
}
template<typename T_obj>
static inline void deallocate(T_obj* ptr){
ptr->free();///allocating by free.
//delete ptr;
}

There must be some problem with your policy: you allocate with new and
deallocate with free: That is UB.

Regards,

Zara
 
T

toton

Zara said:
It must be shared. Never mind the underlying details or the name,
Axter pointer must be shared if it may be used with STdLib containers
And Axter pointer admits the use os different policies pof allocation
and deletion, so there should be no problem with it, AFAIK.



There must be some problem with your policy: you allocate with new and
deallocate with free: That is UB.
No it is not. This free is a virtual member function of the class ( see
it is written as ptr->free() ), not the plane old C free function,
which calls some cleanup routine and then delete this; (i.e suicide
itself), which in turn calls destructor (which don't do anything as
cleanup routine is inside free ! ) . This is just to conform with some
old C++ class written as if free is there destructor rather than the
natural destructor.
Thanks
 
Z

Zara

No it is not. This free is a virtual member function of the class ( see
it is written as ptr->free() ), not the plane old C free function,
which calls some cleanup routine and then delete this; (i.e suicide
itself), which in turn calls destructor (which don't do anything as
cleanup routine is inside free ! ) . This is just to conform with some
old C++ class written as if free is there destructor rather than the
natural destructor.

Ah, yes. Sorry for the comment. 6:00 AM is a bad hour to analyse code.

Best regards,

zara
 
K

Kai-Uwe Bux

Zara said:
Zara wrote: [snip]
If you want to use the pointer with an STL container, it must be
shared, to have the correct copy semantics. So, you must go with
boost::shared_ptr ort tr1::shared_ptr
Not sure, why it have to be shared. Only thing I look for that the
pointer owns the object, and pointer itself is copy constructable. If I
am not wrong, shared_ptr is a reference counted version, and deletes
the object only when all of the references gets out of scope. Thus one
or more container can "own" the object.

It must be shared. Never mind the underlying details or the name,
Axter pointer must be shared if it may be used with STdLib containers

Nope: All it needs to have a reliable and sound semantics under
copy-construction, assignment, and default-construction. There is no
requirement in the standard that pointers in sequences be shared pointers.
A copy_ptr (automagic deep-copy semantics) or a clone_ptr (copy-semantics
via calling a clone method) will do just as fine.

[snip]

Best

Kai-Uwe Bux
 
M

mlimber

toton said:
So the container "owns" the objects but stores the object pointers. And
thus container gets deleted, object should get deleted. Except it calls
destructor (i.e delete ) on the object, while I need to call free on it
(and that is only due to some old codes which are written with free,
not with destructor). shared_ptr can do all the jobs no doubt, however
it have more flexibility than what I need.

It seems to me that shared_ptr has what you need (viz. a custom
deleter) while Axter's smart pointer apparently does not (although we
can't be sure of that since you haven't posted or given us a link to
the code).

You can do one of three things:

1. Add a custom deleter to Axter's smart pointer if it doesn't have
one. (For some hints on how to do this, see Scott Meyers' last "Aha!
Moment" at <http://www.artima.com/cppsource/top_cpp_aha_moments.html>.)

2. Use a shared_ptr and live with the reference counting even though
it's not strictly necessary for your application.

3. Contact Axter and ask him. You haven't really posted enough code for
us to know what your options are.

Cheers! --M
 
T

toton

mlimber said:
It seems to me that shared_ptr has what you need (viz. a custom
deleter) while Axter's smart pointer apparently does not (although we
can't be sure of that since you haven't posted or given us a link to
the code).

You can do one of three things:

1. Add a custom deleter to Axter's smart pointer if it doesn't have
one. (For some hints on how to do this, see Scott Meyers' last "Aha!
Moment" at <http://www.artima.com/cppsource/top_cpp_aha_moments.html>.)
Yes. That's what I deed and it is working find. One can see my post
above about how the custom deleter ( One mistake in comment is there,
instead of ///allocating with free , it should be ///deallocating with
free. And again it is not C free, it is a custom deleter, a virtual
member of the class )
2. Use a shared_ptr and live with the reference counting even though
it's not strictly necessary for your application.
I don't need shared_ptr as nothing is shared, The container "owns" the
object. shared_ptr is more than what I need, and thus adds more
overhead.
May be second (and secondary reason) reason is I need to have a bunch
of code from boost to include it, which is what I don't need for Axter,
and a single class serves all of the purposes. Anyway the is purely my
personal opinion, and one has to choose !
3. Contact Axter and ask him. You haven't really posted enough code for
us to know what your options are.
No need! They provides the source code (They have to! It is template !)
Again here is the code for a custom deleter policy (which deletes by
free member function) . Quite easy and self explanatory.
struct allocator_free_policy{
template<typename T_obj>
static inline T_obj* allocate(const T_obj* ptr){
if (ptr) return new T_obj(*ptr);///allocating by new.
return NULL;
}
template<typename T_obj>
static inline void deallocate(T_obj* ptr){
ptr->free();///deallocating by free.
//delete ptr;
}
Thanks for listening.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top