Boost logo

Boost :

From: Dave Abrahams (abrahams_at_[hidden])
Date: 2000-03-06 05:25:00


on 3/6/00 12:55 AM, Kevin Atkinson at kevinatk_at_[hidden] wrote:

> I want two propose two pseudo smart points which I have found extremely
> useful in my code.
>
> CopyPtr ptr primary used to avoid unnecessary interdependencies and to
> support the pimpl idiom. A typical usage would be:
>
> class Foo {
> class Pimpl;
> CopyPtr<Pimpl> pimpl_;
> };
>
> or
>
> class Bar;
> class Foo {
> CopyPtr<Bar> bar_;
> };
>
> As is usage when ever one CopyPtr gets assigned to another a copy is
> made.

Clearly, to get the benefits of removing interdependencies, you must define
an out-of-line copy constructor and assignment operator. This means you must
remember to write:

Foo::Foo(const Foo& rhs)
    : pimpl_(rhs.pimpl_)
{
}

Foo& Foo::operator=(const Foo& rhs)
{
    //assign bases, other members here
    pimpl_ = rhs.pimpl_;
}
    [or else the strongly-exception-safe swap()-based implementation]

Comparing these with what's required if auto_ptr<> is used instead of
CopyPtr, I don't see much savings.

Foo::Foo(const Foo& rhs)
    : pimpl_(new Pimpl(*rhs.pimpl_))
{
}

Foo& Foo::operator=(const Foo& rhs)
{
    //assign bases, other members here
    pimpl_ = std::auto_ptr<Pimpl>(new Pimpl(*rhs.pimpl_));
}

Okay, I'll concede that the incantation for assignment is simpler, but the
swap-based version is actually identical.

Also, the idea that some CopyPtrs can own their target while others do not
is worrisome to me. It certainly seems like an unneccessary complication and
a good hole to drive bugs through.

Finally, your #include guards are names reserved to the C++ implementation.

-Dave


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