Boost logo

Boost :

From: alexoss_at_[hidden]
Date: 2001-03-18 10:46:09


I created my own reference-counted smart pointer class a long time
ago and have used it quite successfully. However, it suffered from
what kept on turning out to be a serious drawback: it could not be
used for static variables, because it relied on a global structure to
keep track of the allocations it was tracking.

The boost::shared_ptr class is a godsend: it makes very clever use of
new language features like the "explicit" keyword, and templatized
member functions. I have taken the shared_ptr code and modified it
for my purposes, replacing my venerable but limited class. While
test compiling, I have come up with a few questions...

1. In share(), shouldn't the code "if (pn != rpn)" be "if (px !=
rpx)"? In my version, I inlined share() so that the operator =()
looks like:

        template<typename Y>
        shared_ptr &operator =(const shared_ptr<Y> &r)
        {
          if (px != r.px) { dispose(); px = r.px; ++*(pn = r.pn); }
          return(*this);
        }

My assumption is that the purpose of the "if" statement is to prevent
self-assignment, which is not accurately detected if the comparison
is between the counter variables.

2. Why does reset(T *) have different code than operator=
(auto_ptr)? They seem to perform exactly the same operation
(replacing the member values with those passed in as a parameter),
but reset() seems to have a more complicated structure, which is
unnecessary in operator =(). Wouldn't reset() work just as well like:

        void reset(T *p = 0)
        {
          if (px == p) return;
          if (*pn == 1) { delete px; }
          else
          {
            long *tmp = new long(1);
            --*pn;
            pn = tmp;
          }
          px = p;
        }

3. I used the same code in the reset() above to create an operator =
(T *). Is there any harm to providing such an assignment operator,
especially given the existence of a constructor with a pointer
parameter, as well as reset() itself?

4. Why is "long" the type of the reference count variable? Why
isn't it "unsigned long"? The number of referencing pointers cannot
be negative.

5. Is the presence of "typedef T element_type;" a means by which
greater compatibility between shared_ptr and the standard library can
be established?

6. Although I see that it "works" (that is, without it, I get
compilation errors in BCB 5), I cannot fully understand:

template<typename Y> friend class shared_ptr;

What does this code do, exactly?

7. Are there situations in which use_count() and unique() are
helpful to have? I've never needed to know this information about my
old reference-counted pointer class.

Thanks so much for your help, and of course for "pointing" me in the
right direction!

--Alexander J. Oss


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk