实现自己的智能指针
//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr = nullptr)
:mptr(ptr) {}
~CSmartPtr() { delete mptr; }
private:
T *mptr;
};
int main()
{
CSmartPtr<int> ptr1(new int);
return 0;
}
不能把智能指针new在堆上
CSmartPtr *p = new CSmartPtr(new int); //p还是裸指针
重载*
和->
//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr = nullptr)
:mptr(ptr) {}
~CSmartPtr() { delete mptr; }
T& operator*() { return *mptr; }
T* operator->() { return mptr; }
private:
T *mptr;
};
int main()
{
CSmartPtr<int> ptr1(new int);
class Test
{
public:
void test() { cout << "Test::test()" << endl; }
};
CSmartPtr<Test> test(new Test());
test->test();
return 0;
}
/*
不带引用计数的智能指针
auto_ptr:C++库里面
C++11新标准:
scoped_ptr
unique_ptr
*/
auto_ptr<int> ptr1(new int);
auto_ptr<int> ptr2(ptr1);
*ptr2 = 20;
cout << *ptr1 << endl; //ptr1现在为空
//不推荐使用auto_ptr
//scoped_ptr
//scoped_ptr(const scoped_ptr&) = delete;
//scoped_ptr& operator=(const scoped_ptr&) = delete;
unique_ptr
unique_ptr(const unique_ptr<T>&) = delete;
unique_ptr<T>& operator=(const unique_ptr<T>&) = delete;
//实现了右值引用的拷贝
unique_ptr(unique_ptr<T> &&src)
unique_ptr<T>& operator=(unique_ptr<T> &&src)
template<typename T>
unique_ptr<T> getSmartPtr()
{
unique_ptr<T> ptr(new T());
return ptr;
}
unique_ptr<int> ptr1 = getSmartPtr<int>();
unique_ptr<int> p1(new int);
unique_ptr<int> p2(std::move(p1));
引用计数
//对资源进行引用计数的类
template<typename T>
class RefCnt
{
public:
RefCnt(T *ptr = nullptr)
:mptr(ptr)
{
if (mptr != nullptr)
mcount = 1;
}
//增加资源的引用计数
void addRef()
{
mcount++;
}
int delRef() { return --mcount; }
private:
T *mptr;
int mcount;
};
//智能指针 保证能做到资源的自动释放
//利用栈上的对象出作用域自动析构的特征,来做到资源的自动释放的
template<typename T>
class CSmartPtr
{
public:
CSmartPtr(T *ptr = nullptr)
:mptr(ptr)
{
mpRefCnt = new RefCnt<T>(mptr);
}
~CSmartPtr()
{
if (0 == mpRefCnt->delRef())
{
delete mptr;
mptr = nullptr;
}
}
T& operator*() { return *mptr; }
T* operator->() { return mptr; }
CSmartPtr(const CSmartPtr<T> &src)
:mptr(src.mptr), mpRefCnt(src.mpRefCnt)
{
if (mptr != nullptr)
mpRefCnt->addRef();
}
CSmartPtr<T>& operator=(const CSmartPtr<T> &src)
{
if (this == &src)
return *this;
if (0 == mpRefCnt->delRef())
{
delete mptr;
}
mptr = src.mptr;
mpRefCnt = src.mpRefCnt;
mpRefCnt->addRef();
return *this;
}
private:
T *mptr; //指向资源的指针
RefCnt<T> *mpRefCnt; //指向该资源引用计数对象的指针
};
int main()
{
CSmartPtr<int> ptr1(new int);
CSmartPtr<int> ptr2(ptr1);
CSmartPtr<int> ptr3;
ptr3 = ptr2;
*ptr1 = 20;
cout << *ptr2 << " " << *ptr3 << endl;
return 0;
}
循环引用
class B;
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
shared_ptr<B> _ptrb;
};
class B
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
shared_ptr<A> _ptra;
};
int main()
{
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
pa->_ptrb = pb;
pb->_ptra = pa;
cout << pa.use_count() << endl;
cout << pb.use_count() << endl;
return 0;
}
定义对象的时候,用强智能指针;引用对象的地方,使用弱智能指针
class B;
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
weak_ptr<B> _ptrb;
};
class B
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
weak_ptr<A> _ptra;
};
int main()
{
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
pa->_ptrb = pb;
pb->_ptra = pa;
cout << pa.use_count() << endl;
cout << pb.use_count() << endl;
return 0;
}
weak_ptr
只是观察作用,观察资源还可不可用,但是却不能用
class B;
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void testA() { cout << "非常好用的方法" << endl; }
weak_ptr<B> _ptrb;
};
class B
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
void func()
{
_ptra->testA();//使用不了
}
weak_ptr<A> _ptra;
};
在使用时必须进行提升
class B
{
public:
B() { cout << "B()" << endl; }
~B() { cout << "~B()" << endl; }
void func()
{
//_ptra->testA();//使用不了
shared_ptr<A> ps = _ptra.lock(); //提升方法
if (ps != nullptr)
{
ps->testA();
}
}
weak_ptr<A> _ptra;
};
//多线程访问共享对象的线程安全问题
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void testA() { cout << "非常好用的方法!" << endl; }
};
void handler01(A *q)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
//q访问A对象的时候,需要侦测一下A对象是否存活
q->testA();
}
int main()
{
A *p = new A();
thread t1(handler01, p);
delete p;
t1.join();
return 0;
}
class A
{
public:
A() { cout << "A()" << endl; }
~A() { cout << "~A()" << endl; }
void testA() { cout << "非常好用的方法!" << endl; }
};
void handler01(weak_ptr<A> pw)
{
std::this_thread::sleep_for(std::chrono::seconds(2));
shared_ptr<A> sp = pw.lock();
if (sp != nullptr)
{
sp->testA();
}
else
{
cout << "A对象已经析构,不能访问" << endl;
}
}
int main()
{
{
shared_ptr<A> p(new A());
thread t1(handler01, weak_ptr<A>(p));
t1.detach();
}
std::this_thread::sleep_for(std::chrono::seconds(20));
return 0;
}
/*
智能指针的删除器 deletor
智能指针:能够保证资源绝对的释放
*/
//unique_ptr shared_ptr
/*
~unique_ptr() {是一个函数对象的调用 deletor(ptr); }
template
class Deletor
{
public:
void operator()(T *ptr)
{
delete ptr;
}
};
*/
template<typename T>
class MyDeletor
{
public:
void operator()(T *ptr) const
{
cout << "call MyDeletor.operator()" << endl;
delete []ptr;
}
};
int main()
{
unique_ptr<int, MyDeletor<int>> ptr1(new int[100]);
return 0;
}
template<typename T>
class MyFileDeletor
{
public:
void operator()(T *ptr) const
{
cout << "call MyFileDeletor.operator()" << endl;
fclose(ptr);
}
};
int main()
{
unique_ptr<FILE, MyFileDeletor<FILE>> ptr(fopen("data.txt", "w"));
return 0;
}
使用lambda
unique_ptr<int, function<void(int*)>> ptr1(new int[100],
[](int *p)->void {
cout << "call lambda release new int[100]" << endl;
delete[]p;
}
);
unique_ptr<FILE, function<void(FILE*)>> ptr2(fopen("data.txt", "w"),
[](FILE *p)->void {
cout << "call lambda release fopen" << endl;
fclose(p);
}
);