C++编程经验(9):智能指针 -- 裸指针管得了的我要管

}

}

void addRef() {

mcount++;

}

int delRef() {

return --mcount;

}

private:

TT* mptr;

int mcount;

};

template

class smart_ptr {

public:

smart_ptr(T* ptr = nullptr){

mptr = ptr;

mRefCnt = new Refcnt(mptr);

}

~smart_ptr() {

if (0 == mRefCnt->delRef()) {

delete mptr;

mptr = nullptr;

}

}

T& operator*() {

return *(this->mptr);

}

T* operator->() {

return this->mptr;

}

smart_ptr(const smart_ptr& ptr) {

mptr = ptr.mptr;

mRefCnt = ptr.mRefCnt;

if (mptr != nullptr) {

mRefCnt->addRef();

}

}

smart_ptr& operator=(smart_ptr &ptr) {

if (this == &ptr) {

return *this;

}

//要走之前,要先判断一下自己原先的资源有没有人接管

if (0 == mRefCnt->delRef()) {

delete mptr;

}

mptr = ptr.mptr;

mRefCnt = ptr->mRefCnt;

mRefCnt->addRef();

return *this;

}

private:

T* mptr; //指向资源

Refcnt* mRefCnt; //指向引用计数

};

int main() {

smart_ptr sp(new int); //现在这样写就好了

smart_ptr ps(sp);

return 0;

}


智能指针的循环引用问题


强智能指针

使用引用计数的指针有:shared_ptr 和 weak_ptr,一个称为强智能指针,一个称为若智能指针。

强智能指针可以改变资源的引用计数,弱智能指针不会。

我们前面写的那个就是简化版的强智能指针。

但是呢,强智能指针有个很严重的问题,叫做循环引用,或者说“交叉引用”,这么说会不会比较明显点。

#include

#include

using namespace std;

class B;

class A {

public:

A() {

cout << “A” << endl;

}

~A() {

cout << “~A” << endl;

}

shared_ptr _ptrb;

};

class B {

public:

B() {

cout << “B” << endl;

}

~B() {

cout << “~B” << endl;

}

shared_ptr _ptra;

};

int main() {

shared_ptr pa(new A());

shared_ptr pb(new B());

cout << pa.use_count() << endl;

cout << pb.use_count() << endl;

//到这之前都很正常

//pa->_ptrb = pb;

//pb->_ptra = pa;

return 0;

}

A

B

1

1

~B

~A

那我现在把那两行放出来运行呢?

int main() {

shared_ptr pa(new A());

shared_ptr pb(new B());

//到这之前都很正常

pa->_ptrb = pb;

pb->_ptra = pa;

cout << pa.use_count() << endl;

cout << pb.use_count() << endl;

return 0;

}

A

B

2

2

智能指针没有被正确的析构掉,那还能叫智能指针吗?


弱智能指针

从上面的实验我们得出一个结论:在使用对象的时候,使用强智能指针;在引用对象的时候,使用弱智能指针。

怎么得出的呢?总不能说强智能指针不好用了就用弱的吧,主要是弱智能指针不改变计数,但是其实就相当于是一个观察者,对对象其实没有权限的。

改一下上面的代码,把类中的强智能指针改成弱的。再运行就正常。


弱智能指针升级为强智能指针

接下来是不是就要问这个问题嘞?

类B里面去调用类A里面的一个方法,看看行不行。

void testB() {

_ptra->testA();

}

很显然,是不行的。因为弱智能指针只会观察强指针。

那要用的时候怎么办呢?升级:

void testB() {

shared_ptr ps = _ptra.lock(); //就是内个锁

if (ps != nullptr) { //看一下资源是否还在

ps->testA();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值