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; }