feat: C++ implementation of unique_ptr
This commit is contained in:
parent
fa8e6f3c8b
commit
1f3a5e9638
@ -92,26 +92,55 @@ private: //
|
|||||||
mutex* _pMutex; // 计数自增非原子操作,加锁解决多线程
|
mutex* _pMutex; // 计数自增非原子操作,加锁解决多线程
|
||||||
};
|
};
|
||||||
|
|
||||||
int main()
|
//int main()
|
||||||
{
|
//{
|
||||||
SharedPtr<int> sp1(new int(10));
|
// SharedPtr<int> sp1(new int(10));
|
||||||
SharedPtr<int> sp2(sp1);
|
// SharedPtr<int> sp2(sp1);
|
||||||
*sp2 = 20;
|
// *sp2 = 20;
|
||||||
//sp1 与 sp2 在管理这部分资源,引用计数为 2
|
// //sp1 与 sp2 在管理这部分资源,引用计数为 2
|
||||||
cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //2 20
|
// cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //2 20
|
||||||
cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 20
|
// cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 20
|
||||||
|
//
|
||||||
|
// SharedPtr<int> sp3(new int(30));
|
||||||
|
// sp2 = sp3; //sp3 赋值给它,释放管理的旧资源,引用计数-1,
|
||||||
|
// cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //1 20
|
||||||
|
// cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 30
|
||||||
|
// cout << sp3.useCount() << " *ptr:" << *sp3 << endl; //2 30
|
||||||
|
//
|
||||||
|
// sp1 = sp3;
|
||||||
|
// cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //3 30
|
||||||
|
// cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //3 30
|
||||||
|
// cout << sp3.useCount() << " *ptr:" << *sp3 << endl; //3 30
|
||||||
|
//
|
||||||
|
// std::cout << "Hello World!\n";
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
|
||||||
SharedPtr<int> sp3(new int(30));
|
/*******************************************************************
|
||||||
sp2 = sp3; //sp3 赋值给它,释放管理的旧资源,引用计数-1,
|
* 打印结果:
|
||||||
cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //1 20
|
* no default constructor
|
||||||
cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 30
|
* copy constructor
|
||||||
cout << sp3.useCount() << " *ptr:" << *sp3 << endl; //2 30
|
* addRefCount
|
||||||
|
* 2 *ptr:20
|
||||||
sp1 = sp3;
|
* 2 *ptr:20
|
||||||
cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //3 30
|
* no default constructor
|
||||||
cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //3 30
|
* copy assignment constructor
|
||||||
cout << sp3.useCount() << " *ptr:" << *sp3 << endl; //3 30
|
* release
|
||||||
|
* addRefCount
|
||||||
std::cout << "Hello World!\n";
|
* 1 *ptr:20
|
||||||
return 0;
|
* 2 *ptr:30
|
||||||
}
|
* 2 *ptr:30
|
||||||
|
* copy assignment constructor
|
||||||
|
* release
|
||||||
|
* addRefCount
|
||||||
|
* 3 *ptr:30
|
||||||
|
* 3 *ptr:30
|
||||||
|
* 3 *ptr:30
|
||||||
|
* Hello World!
|
||||||
|
* destructor
|
||||||
|
* release
|
||||||
|
* destructor
|
||||||
|
* release
|
||||||
|
* destructor
|
||||||
|
* release
|
||||||
|
******************************************************************/
|
@ -7,14 +7,3 @@
|
|||||||
//{
|
//{
|
||||||
// std::cout << "Hello World!\n";
|
// std::cout << "Hello World!\n";
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu
|
|
||||||
// Debug program: F5 or Debug > Start Debugging menu
|
|
||||||
|
|
||||||
// Tips for Getting Started:
|
|
||||||
// 1. Use the Solution Explorer window to add/manage files
|
|
||||||
// 2. Use the Team Explorer window to connect to source control
|
|
||||||
// 3. Use the Output window to see build output and other messages
|
|
||||||
// 4. Use the Error List window to view errors
|
|
||||||
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project
|
|
||||||
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file
|
|
||||||
|
@ -141,11 +141,13 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="SharedPtr.cpp" />
|
<ClCompile Include="SharedPtr.cpp" />
|
||||||
<ClCompile Include="Studio.cpp" />
|
<ClCompile Include="Studio.cpp" />
|
||||||
|
<ClCompile Include="UniquePtr.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="MemoryAlignment.h" />
|
<ClInclude Include="MemoryAlignment.h" />
|
||||||
<ClInclude Include="SharedPtr.h" />
|
<ClInclude Include="SharedPtr.h" />
|
||||||
<ClInclude Include="SpecialMembers.h" />
|
<ClInclude Include="SpecialMembers.h" />
|
||||||
|
<ClInclude Include="UniquePtr.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
@ -21,6 +21,9 @@
|
|||||||
<ClCompile Include="SharedPtr.cpp">
|
<ClCompile Include="SharedPtr.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="UniquePtr.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="MemoryAlignment.h">
|
<ClInclude Include="MemoryAlignment.h">
|
||||||
@ -32,5 +35,8 @@
|
|||||||
<ClInclude Include="SharedPtr.h">
|
<ClInclude Include="SharedPtr.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="UniquePtr.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
1
Studio/Studio/UniquePtr.cpp
Normal file
1
Studio/Studio/UniquePtr.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "UniquePtr.h"
|
125
Studio/Studio/UniquePtr.h
Normal file
125
Studio/Studio/UniquePtr.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*******************************************************************
|
||||||
|
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
||||||
|
* GitHub: https://github.com/XMuli
|
||||||
|
* Description: C++ 实现一个核心的 unique_ptr 智能指针模板类;
|
||||||
|
* Ref: https://www.jianshu.com/p/77c2988be336
|
||||||
|
* https://juejin.cn/post/7122641980315680782
|
||||||
|
* https://juejin.cn/post/7099967913594978341
|
||||||
|
******************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class UniquePtr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr UniquePtr() : _ptr(nullptr) { cout << "default constructor" << endl; };
|
||||||
|
explicit UniquePtr(T* obj) : _ptr(obj) { cout << "no default constructor" << endl; };
|
||||||
|
|
||||||
|
UniquePtr(UniquePtr<T>&& obj) noexcept
|
||||||
|
: _ptr(obj._ptr)
|
||||||
|
{
|
||||||
|
cout << "move constructor" << endl;
|
||||||
|
obj._ptr = nullptr;
|
||||||
|
}
|
||||||
|
UniquePtr<T>& operator=(UniquePtr<T>&& obj) noexcept
|
||||||
|
{
|
||||||
|
cout << "move assignment constructor" << endl;
|
||||||
|
if (&obj != this) {
|
||||||
|
if (obj._ptr) {
|
||||||
|
_ptr = obj._ptr;
|
||||||
|
obj._ptr = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
UniquePtr(const UniquePtr<T>& obj) = delete; // C++11 delete 禁止方式,C++98 用 private 来隐藏
|
||||||
|
UniquePtr<T>& operator=(const UniquePtr<T>& obj) = delete;
|
||||||
|
|
||||||
|
~UniquePtr()
|
||||||
|
{
|
||||||
|
cout << "destructor" << endl;
|
||||||
|
if (_ptr) {
|
||||||
|
delete _ptr;
|
||||||
|
_ptr = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator*() const { return *_ptr; }
|
||||||
|
T* operator->() const { return _ptr; }
|
||||||
|
T* get() const { return _ptr; }
|
||||||
|
|
||||||
|
T* release() // return std::exchange(_ptr, nullptr); // C++14
|
||||||
|
{
|
||||||
|
T* temp = _ptr;
|
||||||
|
_ptr = nullptr;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(T* ptr) // std::exchange(_ptr, ptr); // C++14
|
||||||
|
{
|
||||||
|
_ptr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(UniquePtr<T>& obj)
|
||||||
|
{
|
||||||
|
std::swap(_ptr, obj._ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* _ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
//int main()
|
||||||
|
//{
|
||||||
|
// UniquePtr<int> up1(new int(10));
|
||||||
|
// cout << "up1:" << up1.get() << " *ptr:" << *up1 << endl;
|
||||||
|
// UniquePtr<int> up2(std::move(up1)); // 控制权变更
|
||||||
|
// cout << "up1:" << up1.get() << endl; // nullptr, 此时 up1 已无控制权
|
||||||
|
// cout << "up2:" << up2.get() << " *ptr:" << *up2 << endl;
|
||||||
|
//
|
||||||
|
// UniquePtr<int> up3(new int(30));
|
||||||
|
// UniquePtr<int> up4(new int(40));
|
||||||
|
// cout << "up3:" << up3.get() << " *ptr:" << *up3 << endl;
|
||||||
|
// cout << "up4:" << up4.get() << " *ptr:" << *up4 << endl;
|
||||||
|
// up3 = std::move(up2); // 控制权变更
|
||||||
|
// cout << "up3:" << up3.get() << " *ptr:" << *up3 << endl;
|
||||||
|
// cout << "up4:" << up4.get() << " *ptr:" << *up4 << endl;
|
||||||
|
// up3.swap(up4);
|
||||||
|
// cout << "up3:" << up3.get() << " *ptr:" << *up3 << endl;
|
||||||
|
// cout << "up4:" << up4.get() << " *ptr:" << *up4 << endl;
|
||||||
|
//
|
||||||
|
// up3.release();
|
||||||
|
// cout << "up3:" << up3.get() << endl;
|
||||||
|
//
|
||||||
|
// std::cout << "Hello World!\n";
|
||||||
|
// return 0;
|
||||||
|
//}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* 打印结果:
|
||||||
|
* no default constructor
|
||||||
|
* up1:01355E78 *ptr:10
|
||||||
|
* move constructor
|
||||||
|
* up1:00000000
|
||||||
|
* up2:01355E78 *ptr:10
|
||||||
|
* no default constructor
|
||||||
|
* no default constructor
|
||||||
|
* up3:01355AF0 *ptr:30
|
||||||
|
* up4:01355B20 *ptr:40
|
||||||
|
* move assignment constructor
|
||||||
|
* up3:01355E78 *ptr:10
|
||||||
|
* up4:01355B20 *ptr:40
|
||||||
|
* up3:01355B20 *ptr:40
|
||||||
|
* up4:01355E78 *ptr:10
|
||||||
|
* up3:00000000
|
||||||
|
* Hello World!
|
||||||
|
* destructor
|
||||||
|
* destructor
|
||||||
|
* destructor
|
||||||
|
* destructor
|
||||||
|
******************************************************************/
|
Loading…
Reference in New Issue
Block a user