feat: std::shared_ptr std::unique_ptr
This commit is contained in:
parent
9894f88b7e
commit
492370ae45
@ -1,7 +1,7 @@
|
|||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
||||||
* GitHub: https://github.com/XMuli
|
* GitHub: https://github.com/XMuli
|
||||||
* Description: 类中字节对齐判断
|
* Description: 类中字节对齐判断
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
// NOTE:
|
// NOTE:
|
||||||
|
@ -1 +1 @@
|
|||||||
#include "SharedPtr.h"
|
#include "SharedPtr.h"
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
||||||
* GitHub: https://github.com/XMuli
|
* GitHub: https://github.com/XMuli
|
||||||
* Description: C++ 实现一个核心的 shared_ptr 智能指针模板类;实现了引用计数是线程安全的,但访问管理的资源不是线程安全的。
|
* Description: C++ 实现一个核心的 shared_ptr 智能指针模板类;实现了引用计数是线程安全的,但访问管理的资源不是线程安全的。
|
||||||
* Note: 书写测试时,若使用默认构造函数, 成员变量 _ptr、_refCount、_pMutex 在 release() 中容易崩溃;推荐带参的构造函数,无错
|
* Note: 书写测试时,若使用默认构造函数, 成员变量 _ptr、_refCount、_pMutex 在 release() 中容易崩溃;推荐带参的构造函数,无错
|
||||||
* Ref: https://juejin.cn/post/7111726931301072910#heading-8
|
* Ref: https://juejin.cn/post/7111726931301072910#heading-8
|
||||||
* https://cloud.tencent.com/developer/article/1688444
|
* https://cloud.tencent.com/developer/article/1688444
|
||||||
* https://blog.csdn.net/Z_Stand/article/details/98512756
|
* 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() : _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(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)
|
: _ptr(obj._ptr)
|
||||||
, _refCount(obj._refCount)
|
, _refCount(obj._refCount)
|
||||||
, _pMutex(obj._pMutex)
|
, _pMutex(obj._pMutex)
|
||||||
@ -34,13 +34,13 @@ public:
|
|||||||
cout << "copy assignment constructor" << endl;
|
cout << "copy assignment constructor" << endl;
|
||||||
if (&obj != this) {
|
if (&obj != this) {
|
||||||
if (_ptr != obj._ptr) {
|
if (_ptr != obj._ptr) {
|
||||||
release(); // 先释放旧的资源
|
release(); // 先释放旧的资源
|
||||||
|
|
||||||
_ptr = obj._ptr;
|
_ptr = obj._ptr;
|
||||||
_refCount = obj._refCount;
|
_refCount = obj._refCount;
|
||||||
_pMutex = obj._pMutex;
|
_pMutex = obj._pMutex;
|
||||||
|
|
||||||
addRefCount(); // 再技计数 +1
|
addRefCount(); // 再技计数 +1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ private:
|
|||||||
bool bDelMutex = false;
|
bool bDelMutex = false;
|
||||||
_pMutex->lock();
|
_pMutex->lock();
|
||||||
|
|
||||||
if (_ptr && --*_refCount == 0) { // 先校验是否存在,及计数为 0 才释放
|
if (_ptr && --*_refCount == 0) { // 先校验是否存在,及计数为 0 才释放
|
||||||
delete _ptr;
|
delete _ptr;
|
||||||
delete _refCount;
|
delete _refCount;
|
||||||
_ptr = nullptr;
|
_ptr = nullptr;
|
||||||
@ -86,10 +86,10 @@ private:
|
|||||||
delete _pMutex;
|
delete _pMutex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private: // 需在构造函数中初始化
|
private: // 需在构造函数中初始化
|
||||||
T* _ptr;
|
T* _ptr; // 指向管理资源的指针
|
||||||
int* _refCount;
|
int* _refCount; // 引用计数
|
||||||
mutex* _pMutex; // 计数自增非原子操作,加锁解决多线程
|
mutex* _pMutex; // 计数自增非原子操作,加锁解决多线程
|
||||||
};
|
};
|
||||||
|
|
||||||
//int main()
|
//int main()
|
||||||
@ -97,12 +97,12 @@ private: //
|
|||||||
// 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));
|
// SharedPtr<int> sp3(new int(30));
|
||||||
// sp2 = sp3; //sp3 赋值给它,释放管理的旧资源,引用计数-1,
|
// sp2 = sp3; //sp3 赋值给它,释放管理的旧资源,引用计数-1,
|
||||||
// cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //1 20
|
// cout << sp1.useCount() << " *ptr:" << *sp1 << endl; //1 20
|
||||||
// cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 30
|
// cout << sp2.useCount() << " *ptr:" << *sp2 << endl; //2 30
|
||||||
// cout << sp3.useCount() << " *ptr:" << *sp3 << endl; //2 30
|
// cout << sp3.useCount() << " *ptr:" << *sp3 << endl; //2 30
|
||||||
@ -116,31 +116,30 @@ private: //
|
|||||||
// return 0;
|
// return 0;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
/*******************************************************************
|
/*****************************打印结果*******************************
|
||||||
* 打印结果:
|
no default constructor
|
||||||
* no default constructor
|
copy constructor
|
||||||
* copy constructor
|
addRefCount
|
||||||
* addRefCount
|
2 *ptr:20
|
||||||
* 2 *ptr:20
|
2 *ptr:20
|
||||||
* 2 *ptr:20
|
no default constructor
|
||||||
* no default constructor
|
copy assignment constructor
|
||||||
* copy assignment constructor
|
release
|
||||||
* release
|
addRefCount
|
||||||
* addRefCount
|
1 *ptr:20
|
||||||
* 1 *ptr:20
|
2 *ptr:30
|
||||||
* 2 *ptr:30
|
2 *ptr:30
|
||||||
* 2 *ptr:30
|
copy assignment constructor
|
||||||
* copy assignment constructor
|
release
|
||||||
* release
|
addRefCount
|
||||||
* addRefCount
|
3 *ptr:30
|
||||||
* 3 *ptr:30
|
3 *ptr:30
|
||||||
* 3 *ptr:30
|
3 *ptr:30
|
||||||
* 3 *ptr:30
|
Hello World!
|
||||||
* Hello World!
|
destructor
|
||||||
* destructor
|
release
|
||||||
* release
|
destructor
|
||||||
* destructor
|
release
|
||||||
* release
|
destructor
|
||||||
* destructor
|
release
|
||||||
* release
|
|
||||||
******************************************************************/
|
******************************************************************/
|
1
Studio/Studio/SpecialMembers.cpp
Normal file
1
Studio/Studio/SpecialMembers.cpp
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "SpecialMembers.h"
|
@ -1,8 +1,8 @@
|
|||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
||||||
* GitHub: https://github.com/XMuli
|
* GitHub: https://github.com/XMuli
|
||||||
* Description: C++ 类的特殊五个函数
|
* Description: C++ 类的特殊五个函数
|
||||||
* Ref:https://en.cppreference.com/w/cpp/language/rule_of_three https://en.wikipedia.org/wiki/Special_member_functions
|
* Ref:https://en.cppreference.com/w/cpp/language/rule_of_three https://en.wikipedia.org/wiki/Special_member_functions
|
||||||
******************************************************************/
|
******************************************************************/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@ -51,7 +51,7 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
A(A&& other) noexcept // 行参无 const
|
A(A&& other) noexcept // 行参无 const
|
||||||
: m_ptr(nullptr) {
|
: m_ptr(nullptr) {
|
||||||
std::cout << "move constructor" << endl;
|
std::cout << "move constructor" << endl;
|
||||||
if (other.m_ptr)
|
if (other.m_ptr)
|
||||||
@ -60,7 +60,7 @@ public:
|
|||||||
other.m_ptr = nullptr;
|
other.m_ptr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
A& operator=(A&& other) noexcept { // 行参无 const
|
A& operator=(A&& other) noexcept { // 行参无 const
|
||||||
std::cout << "move assignment constructor" << endl;
|
std::cout << "move assignment constructor" << endl;
|
||||||
if (this != &other) {
|
if (this != &other) {
|
||||||
delete[] m_ptr; // Free the existing resource.
|
delete[] m_ptr; // Free the existing resource.
|
||||||
@ -89,20 +89,37 @@ A fn() {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
//int main()
|
int main()
|
||||||
//{
|
{
|
||||||
// A a1("a1"); // default constructor
|
A a1("a1"); // default constructor
|
||||||
// A a2(a1); // copy constructor
|
A a2(a1); // copy constructor
|
||||||
// A a3 = a1; // copy constructor
|
A a3 = a1; // copy constructor
|
||||||
// a1 = a3; // copy assignment constructor
|
a1 = a3; // copy assignment constructor
|
||||||
//
|
std::cout << "----------------------------\n\n";
|
||||||
// std::cout << "----------------------------\n\n";
|
|
||||||
//
|
//fn(); // function returning a A object
|
||||||
// //fn(); // function returning a A object
|
A a5 = std::move(a1); // move constructor
|
||||||
// A a5 = std::move(a1); // move constructor
|
A a6; // default constructor
|
||||||
// A a6; // default constructor
|
a6 = std::move(a1); // move assignment constructor
|
||||||
// a6 = std::move(a1); // move assignment constructor
|
std::cout << "Hello World!\n";
|
||||||
// std::cout << "Hello World!\n";
|
|
||||||
//
|
return 0;
|
||||||
// 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
|
||||||
|
******************************************************************/
|
||||||
|
@ -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>
|
#include <iostream>
|
||||||
|
@ -140,6 +140,7 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="SharedPtr.cpp" />
|
<ClCompile Include="SharedPtr.cpp" />
|
||||||
|
<ClCompile Include="SpecialMembers.cpp" />
|
||||||
<ClCompile Include="Studio.cpp" />
|
<ClCompile Include="Studio.cpp" />
|
||||||
<ClCompile Include="UniquePtr.cpp" />
|
<ClCompile Include="UniquePtr.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -24,19 +24,22 @@
|
|||||||
<ClCompile Include="UniquePtr.cpp">
|
<ClCompile Include="UniquePtr.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="SpecialMembers.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="MemoryAlignment.h">
|
<ClInclude Include="MemoryAlignment.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="SpecialMembers.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="SharedPtr.h">
|
<ClInclude Include="SharedPtr.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="UniquePtr.h">
|
<ClInclude Include="UniquePtr.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="SpecialMembers.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1 +1 @@
|
|||||||
#include "UniquePtr.h"
|
#include "UniquePtr.h"
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
* Copyright (c) 2022~2023 XMuli All rights reserved.
|
||||||
* GitHub: https://github.com/XMuli
|
* GitHub: https://github.com/XMuli
|
||||||
* Description: C++ 实现一个核心的 unique_ptr 智能指针模板类;
|
* Description: C++ 实现一个核心的 unique_ptr 智能指针模板类;
|
||||||
* Ref: https://www.jianshu.com/p/77c2988be336
|
* Ref: https://www.jianshu.com/p/77c2988be336
|
||||||
* https://juejin.cn/post/7122641980315680782
|
* https://juejin.cn/post/7122641980315680782
|
||||||
* https://juejin.cn/post/7099967913594978341
|
* https://juejin.cn/post/7099967913594978341
|
||||||
@ -37,7 +37,7 @@ public:
|
|||||||
return *this;
|
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<T>& operator=(const UniquePtr<T>& obj) = delete;
|
||||||
|
|
||||||
~UniquePtr()
|
~UniquePtr()
|
||||||
@ -78,15 +78,15 @@ private:
|
|||||||
//{
|
//{
|
||||||
// UniquePtr<int> up1(new int(10));
|
// UniquePtr<int> up1(new int(10));
|
||||||
// cout << "up1:" << up1.get() << " *ptr:" << *up1 << endl;
|
// cout << "up1:" << up1.get() << " *ptr:" << *up1 << endl;
|
||||||
// UniquePtr<int> up2(std::move(up1)); // 控制权变更
|
// UniquePtr<int> up2(std::move(up1)); // 控制权变更
|
||||||
// cout << "up1:" << up1.get() << endl; // nullptr, 此时 up1 已无控制权
|
// cout << "up1:" << up1.get() << endl; // nullptr, 此时 up1 已无控制权
|
||||||
// cout << "up2:" << up2.get() << " *ptr:" << *up2 << endl;
|
// cout << "up2:" << up2.get() << " *ptr:" << *up2 << endl;
|
||||||
//
|
//
|
||||||
// UniquePtr<int> up3(new int(30));
|
// UniquePtr<int> up3(new int(30));
|
||||||
// UniquePtr<int> up4(new int(40));
|
// UniquePtr<int> up4(new int(40));
|
||||||
// cout << "up3:" << up3.get() << " *ptr:" << *up3 << endl;
|
// cout << "up3:" << up3.get() << " *ptr:" << *up3 << endl;
|
||||||
// cout << "up4:" << up4.get() << " *ptr:" << *up4 << endl;
|
// cout << "up4:" << up4.get() << " *ptr:" << *up4 << endl;
|
||||||
// up3 = std::move(up2); // 控制权变更
|
// up3 = std::move(up2); // 控制权变更
|
||||||
// cout << "up3:" << up3.get() << " *ptr:" << *up3 << endl;
|
// cout << "up3:" << up3.get() << " *ptr:" << *up3 << endl;
|
||||||
// cout << "up4:" << up4.get() << " *ptr:" << *up4 << endl;
|
// cout << "up4:" << up4.get() << " *ptr:" << *up4 << endl;
|
||||||
// up3.swap(up4);
|
// up3.swap(up4);
|
||||||
@ -101,7 +101,7 @@ private:
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* 打印结果:
|
* 打印结果:
|
||||||
* no default constructor
|
* no default constructor
|
||||||
* up1:01355E78 *ptr:10
|
* up1:01355E78 *ptr:10
|
||||||
* move constructor
|
* move constructor
|
||||||
|
Loading…
Reference in New Issue
Block a user