Hmmm

class BufferParams {
public:
        AuthorList & authors();
private:
        /** Use the Pimpl idiom to hide those member variables that would otherwise
            drag in other header files.
         */
        class Impl;
        lyx::support::cow_ptr<Impl> pimpl_;
};

AuthorList & BufferParams::authors()
{
        return pimpl_->authorlist;
}


Non-const member function accesses the non-const version on 
cow_ptr<Impl>::operator->() which creates a copy of Impl. Not good.

The only time we should be creating a copy of Impl is in the BufferParams copy 
constructor or assignment operator.

I think we need Yonat's 'copied_ptr' here. Maybe boostified. Indeed, that's 
what he suggests at 
http://ootips.org/yonat/4dev/smart-pointers.html#WhichMembers

Angus

template <typename T>
class copied_ptr {
public:
        explicit copied_ptr(T * = 0);
        ~copied_ptr();
        copied_ptr(copied_ptr const &);
        copied_ptr & operator=(copied_ptr const &);

        T & operator*() const;
        T * operator->() const;
        T * get() const;

private:
        T * ptr_;
        void copy(copied_ptr const &);
};


template <typename T>
copied_ptr<T>::copied_ptr(T * p)
        : ptr_(p)
{}


template <typename T>
copied_ptr<T>::~copied_ptr()
{
        delete ptr_;
}


template <typename T>
copied_ptr<T>::copied_ptr(copied_ptr const & other)
{
        copy(other.get());
}


template <typename T>
copied_ptr & copied_ptr<T>::operator=(copied_ptr const & other)
{
        if (&other != this) {
                delete ptr_;
                copy(other);
        }
        return *this;
}


template <typename T>
T & copied_ptr<T>::operator*() const
{
        return *ptr_;
}


template <typename T>
T * copied_ptr<T>::operator->() const
{
        return ptr_;
}


template <typename T>
T * copied_ptr<T>::get() const
{
        return ptr_;
}


template <typename T>
void copied_ptr<T>::copy(copied_ptr const & other)
{
        ptr_ = other.ptr_ ? new T(*other.ptr_) : 0;
}


Reply via email to