目录
- #include
- #include
- #include
- #include
- #include
- #include
- #include
-
- struct B {
- virtual void bar() { std::cout << "B::bar\n"; }
- virtual ~B() = default;
- };
- struct D : B
- {
- D() { std::cout << "D::D\n"; }
- ~D() { std::cout << "D::~D\n"; }
- void bar() override { std::cout << "D::bar\n"; }
- };
-
- // 消费 unique_ptr 的函数能以值或以右值引用接收它
- std::unique_ptr
pass_through(std::unique_ptr p) - {
- p->bar();
- return p;
- }
-
- void close_file(std::FILE* fp) { std::fclose(fp); }
-
- int main()
- {
- std::cout << "unique ownership semantics demo\n";
- {
- auto p = std::make_unique
(); // p 是占有 D 的 unique_ptr - auto q = pass_through(std::move(p));
- assert(!p); // 现在 p 不占有任何内容并保有空指针
- q->bar(); // 而 q 占有 D 对象
- } // ~D 调用于此
-
- std::cout << "Runtime polymorphism demo\n";
- {
- std::unique_ptr p = std::make_unique
(); // p 是占有 D 的 unique_ptr - // 作为指向基类的指针
- p->bar(); // 虚派发
-
- std::vector
> v; // unique_ptr 能存储于容器 - v.push_back(std::make_unique
()); - v.push_back(std::move(p));
- v.emplace_back(new D);
- for(auto& p: v) p->bar(); // 虚派发
- } // ~D called 3 times
-
- std::cout << "Custom deleter demo\n";
- std::ofstream("demo.txt") << 'x'; // 准备要读的文件
- {
- std::unique_ptr
void (*)(std::FILE*) > fp(std::fopen("demo.txt", "r"), - close_file);
- if(fp) // fopen 可以打开失败;该情况下 fp 保有空指针
- std::cout << (char)std::fgetc(fp.get()) << '\n';
- } // fclose() 调用于此,但仅若 FILE* 不是空指针
- // (即 fopen 成功)
-
- std::cout << "Custom lambda-expression deleter demo\n";
- {
- std::unique_ptr
void(D*)>> p(new D, [](D* ptr) - {
- std::cout << "destroying from a custom deleter...\n";
- delete ptr;
- }); // p 占有 D
- p->bar();
- } // 调用上述 lambda 并销毁 D
-
- std::cout << "Array form of unique_ptr demo\n";
- {
- std::unique_ptr
p{new D[3]}; - } // 调用 ~D 3 次
- }
- #include
- int main() {
- std::unique_ptr<int> pInt(new int(5));
- std::cout << *pInt;
- }
- #include
- int main() {
- std::unique_ptr<int> pInt2(pInt);//报错
- std::unique_ptr<int> pInt3 = pInt;//报错
- }
- #include
- int main() {
- std::unique_ptr<int> pInt(new int(5));
- std::unique_ptr<int> pInt2(pInt);//报错
- std::unique_ptr<int> pInt3 = pInt;//报错
- std::unique_ptr<int> pInt4 = std::move(pInt);//移动赋值
-
- std::cout << *pInt;
- }
-
- std::unique_ptr<int> clone(int a) {
- std::unique_ptr<int> pInt(new int(a));
- return pInt;
- }
- int main() {
- clone(5);
- std::cout << *clone(5);
- }
- int main() {
- std::unique_ptr<int[]> p(new int[5]{ 1,2,3,4,5 });
- p[0] = 0;
- }
- int main() {
- std::vector
int>> vec; - std::unique_ptr<int> pInt(new int(5));
- vec.push_back(std::move(pInt));
- return 0;
- }
- #ifndef MY_UNIQUE_PTR
- #define MY_UNIQUE_PTR
- #include
- using namespace std;
- template<class _T>
- class MyDeletor
- {
- public:
- MyDeletor() {}
- void operator()(_T* ptr)const
- {
- if (ptr != nullptr)
- {
- delete ptr;
- }
- }
- };
- template <class _Ty, class _Dx = MyDeletor<_Ty>>
- class my_unique_ptr
- {
- private:
- _Ty* _Ptr;
- _Dx _myDeletor;
- public:
- using pointer = _Ty*;
- using element_type = _Ty;
- using delete_type = _Dx;
- public:
- my_unique_ptr(const my_unique_ptr&) = delete;
- my_unique_ptr& operator=(const my_unique_ptr&) = delete;
- my_unique_ptr(pointer _P = nullptr) :_Ptr(_P) { cout << "Create my_unique_ptr" << this << endl; }
- ~my_unique_ptr() {
- if (_Ptr != nullptr)
- {
- _myDeletor(_Ptr);
- _Ptr = nullptr;
- }
- cout << " delete my_unique_ptr" << this << endl;
- }
- my_unique_ptr(my_unique_ptr&& _Y)
- {
- _Ptr = _Y._Ptr;
- _Y._Ptr = nullptr;
- cout << "move copy my_unique_ptr:" << this << endl;
- }
- template <class _Uy>
- my_unique_ptr& operator=(_Uy* _Y)
- {
- if (this->_Ptr == (pointer)_Y)return this;
- if (_Ptr != nullptr) { _myDeletor(_Ptr); }
- _Ptr = _Y;
- return *this;
- }
- my_unique_ptr& operator=(my_unique_ptr&& _Y)
- {
- if (this == &_Y) return *this;
- //reset(_Y.release());
- if (_Ptr != nullptr) _myDeletor(_Ptr);
- _Ptr = _Y._Ptr;
- _Y._Ptr = nullptr;
- cout << "move operatoe=: " << this << endl;
- return *this;
- }
- _Dx& get_deleter()
- {
- return _myDeletor;
- }
- const _Dx& get_deleter()const
- {
- return _myDeletor;
- }
- _Ty& operator*()const
- {
- return *_Ptr;
- }
- pointer operator ->()const
- {
- return _Ptr;
- }
- operator bool()const
- {
- return _Ptr != nullptr;
- }
- pointer get()const
- {
- return _Ptr;
- }
- pointer release()
- {
- _Ty* old = _Ptr;
- _Ptr = nullptr;
- return old;
- }
- void reset(pointer _P = nullptr)
- {
- pointer old = _Ptr;
- _Ptr = _P;
- if (old != nullptr)
- {
- _myDeletor(old);
- }
- }
- void swap(my_unique_ptr _Y)
- {
- std::swap(_Ptr, _Y._Ptr);
- std::swap(_myDeletor, _Y._myDeletor);
- }
-
- };
- template<class _Ty>
- class MyDeletor<_Ty[]>
- {
- public:
- MyDeletor() = default;
- void operator()(_Ty* ptr)const
- {
- if (ptr != nullptr)
- {
- delete[]ptr;
- }
- }
- };
- template <class _Ty, class _Dx >
- class my_unique_ptr<_Ty[], _Dx>
- {
- private:
- _Ty* _Ptr;
- _Dx _myDeletor;
- public:
- using pointer = _Ty*;
- using element_type = _Ty;
- using delete_type = _Dx;
- public:
- my_unique_ptr(const my_unique_ptr&) = delete;
- my_unique_ptr& operator=(const my_unique_ptr&) = delete;
- my_unique_ptr(pointer _P = nullptr) :_Ptr(_P) { cout << "Create my_unique_ptr" << this << endl; }
- ~my_unique_ptr() {
- if (_Ptr != nullptr)
- {
- _myDeletor(_Ptr);
- _Ptr = nullptr;
- }
- cout << " delete my_unique_ptr" << this << endl;
- }
- my_unique_ptr(my_unique_ptr&& _Y)
- {
- _Ptr = _Y._Ptr;
- _Y._Ptr = nullptr;
- cout << "move copy my_unique_ptr:" << this << endl;
- }
- my_unique_ptr& operator=(my_unique_ptr&& _Y)
- {
- if (this == &_Y) return *this;
- reset(_Y.release());
- /*if (_Ptr != nullptr) _myDeletor(_Ptr);
- _Ptr = _Y._Ptr;
- _Y._Ptr = nullptr;*/
- cout << "move operatoe=: " << this << endl;
- return *this;
- }
- _Dx& get_deleter()
- {
- return _myDeletor;
- }
- const _Dx& get_deleter()const
- {
- return _myDeletor;
- }
- _Ty& operator*()const
- {
- return *_Ptr;
- }
- pointer operator ->()const
- {
- return &**this;
- }
- operator bool()const
- {
- return _Ptr != nullptr;
- }
- pointer get()const
- {
- return _Ptr;
- }
- pointer release()
- {
- _Ty* old = _Ptr;
- _Ptr = nullptr;
- return old;
- }
- void reset(pointer _P = nullptr)
- {
- pointer old = _Ptr;
- _Ptr = _P;
- if (old != nullptr)
- {
- _myDeletor(old);
- }
- }
- void swap(my_unique_ptr _Y)
- {
- std::swap(_Ptr, _Y._Ptr);
- std::swap(_myDeletor, _Y._myDeletor);
- }
- _Ty& operator [](size_t _Index)const
- {
- return _Ptr[_Index];
- }
-
- };
- template<class _Ty, class ..._Type>
- my_unique_ptr<_Ty>my_make_unique(_Type&&..._arys)
- {
- return my_unique_ptr<_Ty>(new _Ty(_arys...));
- }