From ea285b42314abf9c3dbba3f1109ff28ca9769582 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 22 Nov 2002 14:41:22 +0000 Subject: [PATCH] Fixed the previous weak_ptr 'fix'. [SVN r16370] --- include/boost/weak_ptr.hpp | 47 ++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/include/boost/weak_ptr.hpp b/include/boost/weak_ptr.hpp index d08fa5d..cce5cb8 100644 --- a/include/boost/weak_ptr.hpp +++ b/include/boost/weak_ptr.hpp @@ -16,8 +16,6 @@ #include -#include // for std::memcpy - #ifdef BOOST_MSVC // moved here to work around VC++ compiler crash # pragma warning(push) # pragma warning(disable:4284) // odd return type for operator-> @@ -26,6 +24,8 @@ namespace boost { +template shared_ptr make_shared(weak_ptr const & r); // never throws + template class weak_ptr { private: @@ -43,12 +43,39 @@ public: // generated copy constructor, assignment, destructor are fine + +// +// The simple implementation of the converting constructor: +// +// template +// weak_ptr(weak_ptr const & r): px(r.px), pn(r.pn) // never throws +// { +// } +// +// has a serious problem. +// +// r.px may already have been invalidated. The px(r.px) +// conversion may require access to *r.px (virtual inheritance). +// +// It is not possible to avoid spurious access violations since +// in multithreaded programs r.px may be invalidated at any point. +// +// A safe conversion between weak_ptr and weak_ptr must involve +// a temporary shared_ptr. +// +// It is not yet clear whether the converting constructor should be +// present at all, or it's better to require an explicit make_shared call. +// +// The only case for the converting constructor is the weak_ptr -> weak_ptr +// conversion. +// + template - weak_ptr(weak_ptr const & r): pn(r.pn) // never throws + weak_ptr(weak_ptr const & r) // never throws { - // r.px may be an invalid pointer value - using namespace std; - memcpy(&this->px, &r.px, sizeof(r.px)); + shared_ptr tmp = make_shared(r); + px = tmp.px; + pn = tmp.pn; } template @@ -58,14 +85,6 @@ public: #if !defined(BOOST_MSVC) || (BOOST_MSVC > 1200) - template - weak_ptr & operator=(weak_ptr const & r) // never throws - { - px = r.px; - pn = r.pn; - return *this; - } - template weak_ptr & operator=(shared_ptr const & r) // never throws {