Skip to content

Commit

Permalink
added 16_28.
Browse files Browse the repository at this point in the history
  • Loading branch information
pezy committed Apr 11, 2018
1 parent 14198d8 commit f9fa588
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
2 changes: 2 additions & 0 deletions ch16/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ Solution from [How is a template instantiated? - Stack Overflow](https://stackov
> Write your own versions of `shared_ptr` and `unique_ptr`.
[shared_ptr](ex16_28_shared_ptr.h) | [unique_ptr](ex16_28_unique_ptr.h) | [test](ex16_28_test.cpp)
## Exercise 16.29
> Revise your `Blob` class to use your version of `shared_ptr` rather than the library version.
Expand Down
65 changes: 65 additions & 0 deletions ch16/ex16_28_shared_ptr.h
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_
40 changes: 40 additions & 0 deletions ch16/ex16_28_test.cpp
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 added ch16/ex16_28_unique_ptr.h
Empty file.

0 comments on commit f9fa588

Please sign in to comment.