feat: std::shared_ptr std::unique_ptr

This commit is contained in:
XMuli 2022-12-19 01:53:50 +08:00
parent 9894f88b7e
commit 492370ae45
No known key found for this signature in database
GPG Key ID: 9554B5DD5B8E986A
10 changed files with 98 additions and 77 deletions

View File

@ -1,7 +1,7 @@
/*******************************************************************
/*******************************************************************
* Copyright (c) 2022~2023 XMuli All rights reserved.
* GitHub: https://github.com/XMuli
* Description:
* Description:
******************************************************************/
// NOTE:

View File

@ -1 +1 @@
#include "SharedPtr.h"
#include "SharedPtr.h"

View File

@ -1,8 +1,8 @@
/*******************************************************************
/*******************************************************************
* Copyright (c) 2022~2023 XMuli All rights reserved.
* GitHub: https://github.com/XMuli
* Description: C++ shared_ptr 线访线
* Note: 使, _ptr_refCount_pMutex release()
* Description: C++ shared_ptr 线访线
* Note: 使, _ptr_refCount_pMutex release()
* Ref: https://juejin.cn/post/7111726931301072910#heading-8
* https://cloud.tencent.com/developer/article/1688444
* https://blog.csdn.net/Z_Stand/article/details/98512756
@ -20,7 +20,7 @@ public:
SharedPtr() : _ptr(nullptr), _refCount(nullptr), _pMutex(nullptr) { cout << "default constructor" << endl; };
SharedPtr(T* obj) : _ptr(obj), _refCount(new int(1)), _pMutex(new mutex) { cout << "no default constructor" << endl; };
SharedPtr(const SharedPtr<T>& obj) // 其 _refCount 可以通过另外一个指针来修改,指向的是同一个地址
SharedPtr(const SharedPtr<T>& obj) // 其 _refCount 可以通过另外一个指针来修改,指向的是同一个地址
: _ptr(obj._ptr)
, _refCount(obj._refCount)
, _pMutex(obj._pMutex)
@ -34,13 +34,13 @@ public:
cout << "copy assignment constructor" << endl;
if (&obj != this) {
if (_ptr != obj._ptr) {
release(); // 先释放旧的资源
release(); // 先释放旧的资源
_ptr = obj._ptr;
_refCount = obj._refCount;
_pMutex = obj._pMutex;
addRefCount(); // 再技计数 +1
addRefCount(); // 再技计数 +1
}
}
@ -72,7 +72,7 @@ private:
bool bDelMutex = false;
_pMutex->lock();
if (_ptr && --*_refCount == 0) { // 先校验是否存在,及计数为 0 才释放
if (_ptr && --*_refCount == 0) { // 先校验是否存在,及计数为 0 才释放
delete _ptr;
delete _refCount;
_ptr = nullptr;
@ -86,10 +86,10 @@ private:
delete _pMutex;
}
private: // 需在构造函数中初始化
T* _ptr;
int* _refCount;
mutex* _pMutex; // 计数自增非原子操作,加锁解决多线程
private: // 需在构造函数中初始化
T* _ptr; // 指向管理资源的指针
int* _refCount; // 引用计数
mutex* _pMutex; // 计数自增非原子操作,加锁解决多线程
};
//int main()
@ -97,12 +97,12 @@ private: //
// SharedPtr<int> sp1(new int(10));
// SharedPtr<int> sp2(sp1);
// *sp2 = 20;
// //sp1 与 sp2 在管理这部分资源,引用计数为 2
// //sp1 与 sp2 在管理这部分资源,引用计数为 2
// cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //2 20
// cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 20
//
// SharedPtr<int> sp3(new int(30));
// sp2 = sp3; //sp3 赋值给它,释放管理的旧资源,引用计数-1
// 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
@ -116,31 +116,30 @@ private: //
// return 0;
//}
/*******************************************************************
* :
* no default constructor
* copy constructor
* addRefCount
* 2 *ptr:20
* 2 *ptr:20
* no default constructor
* copy assignment constructor
* release
* addRefCount
* 1 *ptr:20
* 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
/*****************************打印结果*******************************
no default constructor
copy constructor
addRefCount
2 *ptr:20
2 *ptr:20
no default constructor
copy assignment constructor
release
addRefCount
1 *ptr:20
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
******************************************************************/

View File

@ -0,0 +1 @@
#include "SpecialMembers.h"

View File

@ -1,8 +1,8 @@
/*******************************************************************
/*******************************************************************
* Copyright (c) 2022~2023 XMuli All rights reserved.
* GitHub: https://github.com/XMuli
* Description: C++
* Refhttps://en.cppreference.com/w/cpp/language/rule_of_three https://en.wikipedia.org/wiki/Special_member_functions
* Description: C++
* Refhttps://en.cppreference.com/w/cpp/language/rule_of_three https://en.wikipedia.org/wiki/Special_member_functions
******************************************************************/
#pragma once
@ -51,7 +51,7 @@ public:
return *this;
}
A(A&& other) noexcept // 行参无 const
A(A&& other) noexcept // 行参无 const
: m_ptr(nullptr) {
std::cout << "move constructor" << endl;
if (other.m_ptr)
@ -60,7 +60,7 @@ public:
other.m_ptr = nullptr;
}
A& operator=(A&& other) noexcept { // 行参无 const
A& operator=(A&& other) noexcept { // 行参无 const
std::cout << "move assignment constructor" << endl;
if (this != &other) {
delete[] m_ptr; // Free the existing resource.
@ -89,20 +89,37 @@ A fn() {
return t;
}
//int main()
//{
// A a1("a1"); // default constructor
// A a2(a1); // copy constructor
// A a3 = a1; // copy constructor
// a1 = a3; // copy assignment constructor
//
// std::cout << "----------------------------\n\n";
//
// //fn(); // function returning a A object
// A a5 = std::move(a1); // move constructor
// A a6; // default constructor
// a6 = std::move(a1); // move assignment constructor
// std::cout << "Hello World!\n";
//
// return 0;
//}
int main()
{
A a1("a1"); // default constructor
A a2(a1); // copy constructor
A a3 = a1; // copy constructor
a1 = a3; // copy assignment constructor
std::cout << "----------------------------\n\n";
//fn(); // function returning a A object
A a5 = std::move(a1); // move constructor
A a6; // default constructor
a6 = std::move(a1); // move assignment constructor
std::cout << "Hello World!\n";
return 0;
}
/*************************** 运行结果 *******************************
* no-default-val constructor
copy constructor
copy constructor
copy assignment constructor
----------------------------
move constructor
default constructor
move assignment constructor
Hello World!
destructor
destructor
destructor
destructor
destructor
******************************************************************/

View File

@ -1,4 +1,4 @@
// Studio.cpp : This file contains the 'main' function. Program execution begins and ends there.
// Studio.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>

View File

@ -140,6 +140,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="SharedPtr.cpp" />
<ClCompile Include="SpecialMembers.cpp" />
<ClCompile Include="Studio.cpp" />
<ClCompile Include="UniquePtr.cpp" />
</ItemGroup>

View File

@ -24,19 +24,22 @@
<ClCompile Include="UniquePtr.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SpecialMembers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="MemoryAlignment.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SpecialMembers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SharedPtr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UniquePtr.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="SpecialMembers.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

View File

@ -1 +1 @@
#include "UniquePtr.h"
#include "UniquePtr.h"

View File

@ -1,7 +1,7 @@
/*******************************************************************
/*******************************************************************
* Copyright (c) 2022~2023 XMuli All rights reserved.
* GitHub: https://github.com/XMuli
* Description: C++ unique_ptr
* Description: C++ unique_ptr
* Ref: https://www.jianshu.com/p/77c2988be336
* https://juejin.cn/post/7122641980315680782
* https://juejin.cn/post/7099967913594978341
@ -37,7 +37,7 @@ public:
return *this;
}
UniquePtr(const UniquePtr<T>& obj) = delete; // C++11 delete 禁止方式C++98 用 private 来隐藏
UniquePtr(const UniquePtr<T>& obj) = delete; // C++11 delete 禁止方式C++98 用 private 来隐藏
UniquePtr<T>& operator=(const UniquePtr<T>& obj) = delete;
~UniquePtr()
@ -78,15 +78,15 @@ private:
//{
// 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 已无控制权
// 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); // 控制权变更
// up3 = std::move(up2); // 控制权变更
// cout << "up3:" << up3.get() << " *ptr:" << *up3 << endl;
// cout << "up4:" << up4.get() << " *ptr:" << *up4 << endl;
// up3.swap(up4);
@ -101,7 +101,7 @@ private:
//}
/*******************************************************************
* :
* :
* no default constructor
* up1:01355E78 *ptr:10
* move constructor