Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Constness of the container of shared_ptr and the constness of it elements

Reply
Thread Tools

Constness of the container of shared_ptr and the constness of it elements

 
 
Roland Pibinger
Guest
Posts: n/a
 
      04-03-2006
On Mon, 03 Apr 2006 16:16:36 GMT, red floyd <(E-Mail Removed)> wrote:
>red floyd wrote:
>Follow-up. You can store pointers (raw or smart) in a Standard
>container. In fact, that's the only way to maintain a container of
>polymorphic objects.


Not the only way. You can store polymorphic objects in any container
that is appropriate for polymorphic objects. Just the Standard
containers are not.

>The thing is that if you store raw pointers in a container, then *you*
>are responsible for managing the lifetime of those pointers


Containment an ownership management are two different tasks. A
container for pointers should be first and foremost a container, not
an object manager.

>-- on a
>recent project, we were using raw pointers (legacy code), and I made a
>big deal during design reviews that pointer ownership and lifetime
>maintenance had to be specified in the design (we were storing them in
>containers).


The rule of thumb is simple: Release resources in destructors. WRT
containers for pointers this means that the destructor of the
containing object shall delete the pointed-to objects in the
container.
A general-purpose container for pointers shall not and cannot delete
any objects (since it doesn't know how they have been created).

>If you use a smart pointer, then the smart pointer manages the lifetime
>of the pointer, and you don't have to deal with it.


The "smart" pointer solution means one resource manager (which
dynamically allocates a ref-counter) for each pointed-to object.
Moreover, "smart" pointers cause many unsmart problems. I would avoid
them.

Best wishes,
Roland Pibinger
 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      04-03-2006
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> In the following program, I want an iterator contain pointer pointing
> to constant object not const pointer. If it is possible would you
> please let me know how to do it?
>
> #include <boost/shared_ptr.hpp>
> #include <vector>
> #include <iterator>
> #include <iostream>
>
> class trial {
> public:
> void const_fun() const {
> std::cout << __PRETTY_FUNCTION__ << std::endl;
> }
> void non_const_fun() {
> std::cout << __PRETTY_FUNCTION__ << std::endl;
> }
> };
>
> int main(){
> std::vector<boost::shared_ptr<trial> > v;
> v.push_back(boost::shared_ptr<trial>(new trial));
> {
> std::vector<boost::shared_ptr<trial> >::iterator it = v.begin();
> (*it)->const_fun();
> (*it)->non_const_fun();
> }
> {
> std::vector<boost::shared_ptr<trial> >::const_iterator it =
> v.begin();
> (*it)->const_fun();
> (*it)->non_const_fun();//want a const trial, this function should
> not be called.
> }
> {
> std::vector<boost::shared_ptr<const trial> >::iterator it =
> v.begin();//compile error
> (*it)->const_fun();
> (*it)->non_const_fun();
> }
>
> std::vector<boost::shared_ptr<const trial> > v_const = v;//error,
> //is there any conversion of
> this kind?
>
> return EXIT_SUCCESS;
> }


There have been several debates on the Boost development group about
whether or not to give smart pointers "deep constness" (see for
instance http://thread.gmane.org/gmane.comp.l...t.devel/95836).
This issue is particularly important when considering const member
functions that can change the pointees of its class' const members. For
instance,

class Foo
{
int *pi_;
std::vector<int> vi_;
public:
// ...

void Bar() const
{
pi_[0] = 0; // Ok, but unintended?
vi_[0] = 0; // Error! vi_ is const here
}
};

Boost smart pointers, like raw pointers, allow modification of the
pointees, but some standard containers like std::vector don't. Because
the goal for boost::shared_ptr was to be "as close as possible to a raw
pointer, but no closer", the final decision was to make it not support
deep constness.

To change the behavior of a smart pointer for members, you might use a
wrapper class like this:

template <typename T>
class deep_shared_ptr
{
public:
// Constructors
deep_shared_ptr() {}

template<typename Y>
deep_shared_ptr( Y* const y ) : m_ptr( y ) {}

template<typename Y>
deep_shared_ptr( boost::shared_ptr<Y>& that ) : m_ptr( that ) {}

template<typename Y>
deep_shared_ptr( deep_shared_ptr<Y>& that ) : m_ptr( that ) {}


// The usual operations
T* operator->() { return m_ptr.operator->(); }
T& operator*() { return m_ptr.operator*(); }


// The unusual: make pointee const if pointer is const
T const* operator->() const { return m_ptr.operator->(); }
T const& operator*() const { return m_ptr.operator*(); }


// Reset pass-throughs
template<typename Y>
void reset( Y* const y )
{ m_ptr.reset( y ); }

template<typename Y>
void reset( boost::shared_ptr<Y>& that )
{ m_ptr.reset( that ); }

template<typename Y>
void reset( deep_shared_ptr<Y>& that )
{ m_ptr.reset( that.Get() ); }


private:
boost::shared_ptr<T> m_ptr;

// Disable copying from const deep pointers
deep_shared_ptr( const deep_shared_ptr& );
deep_shared_ptr( const boost::shared_ptr<T>& );

template<typename Y>
deep_shared_ptr& operator=( const deep_shared_ptr<Y>& );

template<typename Y>
deep_shared_ptr& operator=( const boost::shared_ptr<Y>& );
};

Unfortunately, as is reflected in the disabled functions, deep pointers
of this kind do not support normal copy semantics since they don't
accept a copy from a const deep_shared_ptr and can thus cannot be used
in standard containers. They can be handy as members, however.

Cheers! --M

 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      04-03-2006
Roland Pibinger wrote:
> On Mon, 03 Apr 2006 10:37:28 +1200, Ian Collins <(E-Mail Removed)>
> wrote:
>
>>Roland Pibinger wrote:
>>
>>>No. Standard containers are for values only, not for pointers (neither
>>>real nor "smart").
>>>

>>
>>Care to elaborate? Containers are often used for both pointers and
>>smart pointers.

>
>
> 'Value semantics' is one of the central characteristics of STL. All
> containers, iterators and algorithms are designed for values only. You
> may also use pointers as template arguments but they cause various
> problems: clumsiness in usage, no 'const correctness' (see above),
> algorithm mismatch (algorithms refer to pointers, not pointed-to
> objects), ...
> A container for pointers needs a design that is especially made for
> pointers. Many library vendors provide (non-Standard) containers for
> pointers, see e.g. CTypedPtrArray (MFC), QPtrVector (Qt), ... IMO, the
> lack of appropriate containers for pointers is one of the major
> reasons for the low acceptance of STL in the real world.
>

So what disqualifies a smart pointer from being an object that can be
stored in a container?

--
Ian Collins.
 
Reply With Quote
 
Roland Pibinger
Guest
Posts: n/a
 
      04-03-2006
On Tue, 04 Apr 2006 09:57:47 +1200, Ian Collins <(E-Mail Removed)>
wrote:
>So what disqualifies a smart pointer from being an object that can be
>stored in a container?


It compiles but it doesn't really work. For the reasons pointed out
above.

Best wishes,
Roland Pibinger
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      04-04-2006
Roland Pibinger wrote:
> On Tue, 04 Apr 2006 09:57:47 +1200, Ian Collins <(E-Mail Removed)>
> wrote:
>
>>So what disqualifies a smart pointer from being an object that can be
>>stored in a container?

>
>
> It compiles but it doesn't really work. For the reasons pointed out
> above.
>

Well smart pointers can help.

I'd expect containers to be used as simple storage with pointers, as you
say, the standard algorithms expect value semantics. It makes no sense
to apply std::sort to a vector of pointers, but a vector of pointers is
still preferable to a plain array of pointers.

If you wanted to use the object pointed to, you could provide the
appropriate operators on a smart pointer object.

You could also use a smart pointer to const type to enforce const
correctness.

Provided the user understands the limitations, standard containers are a
good home for (smart) pointers.

--
Ian Collins.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
number of distinct elements in a const container and iterating over the distinct elements Hicham Mouline C++ 1 04-11-2010 10:56 AM
#include <boost/shared_ptr.hpp> or #include "boost/shared_ptr.hpp"? Colin Caughie C++ 1 08-29-2006 02:19 PM
Copy elements from one STL container to another STL container Marko.Cain.23@gmail.com C++ 4 02-16-2006 05:03 PM
container elements for repeating elements ('element farms') needed? Wolfgang Lipp XML 1 01-30-2004 04:09 PM
container elements for repeating elements ('element farms') needed? Wolfgang Lipp XML 0 01-28-2004 02:50 PM



Advertisments