forked from pezy/CppPrimer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#ifndef CP5_EX16_28_SHARED_PTR_H_ | ||
#define CP5_EX16_28_SHARED_PTR_H_ | ||
|
||
#include "ex16_21_debugdelete.h" | ||
#include <functional> | ||
|
||
template <typename T> class SharedPtr { | ||
public: | ||
friend void swap(SharedPtr& lhs, SharedPtr& rhs) | ||
{ | ||
using std::swap; | ||
swap(lhs.ptr_, rhs.ptr_); | ||
swap(lhs.count_ptr_, rhs.count_ptr_); | ||
swap(lhs.delete_, rhs.deleter_); | ||
} | ||
|
||
SharedPtr(T* ptr = nullptr, const std::function<void(T*)>& del = DebugDelete()) | ||
: ptr_(ptr), count_ptr_(new size_t(ptr != nullptr)), deleter_(del) | ||
{ | ||
} | ||
|
||
~SharedPtr() | ||
{ | ||
if (!ptr_) return; | ||
if (--*count_ptr_ == 0) { | ||
deleter_(ptr_); | ||
delete count_ptr_; | ||
} | ||
ptr_ = nullptr; | ||
count_ptr_ = nullptr; | ||
} | ||
|
||
SharedPtr(const SharedPtr& sp) : ptr_(sp.ptr_), count_ptr_(sp.count_ptr_), deleter_(sp.deleter_) | ||
{ | ||
++*count_ptr_; | ||
} | ||
|
||
SharedPtr& operator=(SharedPtr sp) | ||
{ | ||
swap(*this, sp); | ||
return *this; | ||
} | ||
|
||
SharedPtr(const SharedPtr&& sp) noexcept : SharedPtr() { swap(*this, sp); } | ||
|
||
void reset(T* ptr = nullptr, const std::function<void(T*)>& del = DebugDelete()) | ||
{ | ||
swap(*this, SharePtr(ptr, del)); | ||
} | ||
|
||
void swap(SharedPtr& r) noexcept { swap(*this, r); } | ||
|
||
T* get() const noexcept { return ptr_; } | ||
T& operator*() const noexcept { return *get(); } | ||
T* operator->() const noexcept { return get(); } | ||
size_t use_count() const noexcept { return *count_ptr_; } | ||
explicit operator bool() const noexcept { return ptr_ != nullptr; } | ||
|
||
private: | ||
T* ptr_ = nullptr; | ||
size_t* count_ptr_ = nullptr; | ||
std::function<void(T*)> deleter_; | ||
}; | ||
|
||
#endif // CP5_EX16_28_SHARED_PTR_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
#include "ex16_28_shared_ptr.h" | ||
#include <iostream> | ||
|
||
struct Foo { | ||
Foo() { std::cout << "Foo()\n"; } | ||
~Foo() { std::cout << "~Foo()\n"; } | ||
}; | ||
|
||
struct D { | ||
void operator()(Foo* p) const | ||
{ | ||
std::cout << "Call delete from function object...\n"; | ||
delete p; | ||
} | ||
}; | ||
|
||
int main() | ||
{ | ||
{ | ||
std::cout << "constructor with no managed object\n"; | ||
SharedPtr<Foo> sh1; | ||
} | ||
|
||
{ | ||
std::cout << "constructor with object\n"; | ||
SharedPtr<Foo> sh2(new Foo); | ||
SharedPtr<Foo> sh3(sh2); | ||
std::cout << sh2.use_count() << '\n'; | ||
std::cout << sh3.use_count() << '\n'; | ||
} | ||
|
||
{ | ||
std::cout << "constructor with object and deleter\n"; | ||
SharedPtr<Foo> sh4(new Foo, D()); | ||
SharedPtr<Foo> sh5(new Foo, [](Foo* p) { | ||
std::cout << "Call delete from lambda...\n"; | ||
delete p; | ||
}); | ||
} | ||
} |
Empty file.