From 27c66f099b5bc0e320f77da82fb4c0a9e36f0265 Mon Sep 17 00:00:00 2001 From: Robert Sesek <rsesek@bluestatic.org> Date: Sat, 8 Oct 2016 15:29:59 -0400 Subject: [PATCH] Fix ref::operator= for non-const lvalue binding to a temporary. Implement operator= manually and reimplement the copy-ctor using it, rather than vice versa. In addition, deleter_ gets changed to a pointer rather than reference, so that a default ctor can be added. --- test.cc | 18 ++++++++++++++++-- zcpointer.h | 26 ++++++++++++++++---------- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/test.cc b/test.cc index 92da993..4ea07e0 100644 --- a/test.cc +++ b/test.cc @@ -38,7 +38,10 @@ void TestReset() { template <typename T> void TestUnwrap() { zc::owned<T> t(new T()); - T* unwrap = t.get(); + //T* unwrap = t.get(); + + zc::ref<T> ref = t.get(); + T* unwrap2 = ref; } void TestMove() { @@ -52,6 +55,17 @@ void TestMove() { owned->DoThing(); } +void PtrHelper(zc::ref<C>* out) { + zc::owned<C> c(new C()); + *out = c.get(); +} + +void TestPtr() { + zc::ref<C> ref; + PtrHelper(&ref); + ref->DoThing(); +} + int main() { - TestMove(); + TestPtr(); } diff --git a/zcpointer.h b/zcpointer.h index ce4a821..bf86fb5 100644 --- a/zcpointer.h +++ b/zcpointer.h @@ -86,23 +86,29 @@ class owned : public std::unique_ptr<T, internal::OwnedPtrDeleter<T>> { template <typename T> class ref { public: - explicit ref(owned<T>& o) : ptr_(o.GetRawPointer()), deleter_(o.get_deleter()) { - deleter_.AddRef(this); + ref() : ptr_(nullptr), deleter_(nullptr), deleted_(true) {} + + explicit ref(owned<T>& o) : ptr_(o.GetRawPointer()), deleter_(&o.get_deleter()) { + deleter_->AddRef(this); } - ref(const ref<T>& o) : ptr_(o.ptr_), deleter_(o.deleter_), deleted_(o.deleted_) { - if (!deleted_) { - deleter_.AddRef(this); - } + ref(const ref<T>& o) { + *this = o; } - ref<T>& operator=(ref<T> o) { - return ref(o); + ref<T>& operator=(const ref<T>& o) { + ptr_ = o.ptr_; + deleter_ = o.deleter_; + deleted_ = o.deleted_; + if (!deleted_) { + deleter_->AddRef(this); + } + return *this; } ~ref() { MarkDeleted(); - deleter_.RemoveRef(this); + deleter_->RemoveRef(this); } T* operator->() const { @@ -125,7 +131,7 @@ class ref { } T* ptr_; - internal::OwnedPtrDeleter<T>& deleter_; + internal::OwnedPtrDeleter<T>* deleter_; bool deleted_ = false; }; -- 2.43.5