#include <iostream>
#include <memory>
using namespace std;
class SharedInt {
public:
SharedInt(int* p) :m_pPtr(p), m_pRep(new int(1)) {
}
SharedInt(SharedInt& ref) {
*this = ref;
}
SharedInt& operator=(SharedInt& ref) {
if (this!=&ref){
release();
(*ref.m_pRep)++;
m_pPtr = ref.m_pPtr;
m_pRep = ref.m_pRep;
}
return *this;
}
~SharedInt() {
release();
}
int refCount()const {
return m_pRep ? *m_pRep : 0;
}
int* data()const {
return m_pPtr;
}
int& operator*() {
return *m_pPtr;
}
private:
void release() {
if (m_pRep != nullptr && --(*m_pRep) == 0) {
delete m_pPtr;
m_pPtr = nullptr;
delete m_pRep;
m_pRep = nullptr;
}
}
int* m_pPtr;//ptr
int* m_pRep;//ref count pointer
};
void main() {
int* p = new int(123);
{
SharedInt si1(p);
cout << si1.refCount() << endl;//1
SharedInt si2 = si1;
cout << si1.refCount()<<" "<<si2.refCount() << endl;//2 2
}
//至此,p内存释放了
}
重新用模版实现,增加一些严谨的类型判断stl模版函数,原子变量的引用计数。
1.计数器是不是线程安全的?
2.shared_ptr是不是线程安全的?
3.T是不是线程安全的?
4.c++委员会对std::shared_ptr源代码有什么要求?在不同std实现是否相同?最细要求是什么?
A std::shared_ptr consists of a control block and its resource. Yes, the control block is thread-safe; but no, the access to the resource is not thread-safe. That means, modifying the reference counter is an atomic operation and you have the guarantee that the resource will be deleted exactly once.
If multiple threads of execution access the same shared_ptr
object without synchronization and any of those accesses uses a non-const member function of shared_ptr
then a data race will occur; the std::atomic<shared_ptr> can be used to prevent the data race.
std::shared_ptr由一个控制块及其资源组成。是的,控制块是线程安全的;但是不,对资源的访问不是线程安全的。这意味着,修改引用计数器是一个原子操作,您可以保证资源将被删除一次。
如果多个执行线程在没有同步的情况下访问同一个shared_ptr对象,并且这些访问中的任何一个使用shared_ptr的非常量成员函数,则将发生数据竞赛; std::atomic<shared_ptr> 可以用于防止数据竞争。