c++中几种针

auto_ptr 

#include <iostream>
#include <memory>
using namespace std;

class A
{
private:
	int _a;
public:
	A(int a){ _a=a; }
	void print(){ cout<<"A::print " << this->_a<<endl; }
};

int main()
{
	std::auto_ptr<A>pa1(new A(1));
	pa1->print();
	cout<<"pa1 pointer: "<<pa1.get()<<endl;

	std::auto_ptr<A>pa2(pa1);	// copy constructor
	pa2->print();
	cout<<"pa1 pointer: "<<pa1.get()<<endl;
	cout<<"pa2 pointer: "<<pa2.get()<<endl;
	pa1->print();

	return 0;
}

上面的代码运行的结果如下:

可以看到最后一个函数调用出现了错误,这是由于auto_ptr具有排他所有权导致的,因为上面的p1将自己对某个对象的所有权限让给了p2, 他就无法再访问只属于这个对象的内容了

但我代码给成这样,

class A
{
// private:
//	int _a;
public:
//	A(int a){ _a=a; }
	void print(){ cout<<"A::print "<<endl; }
};

int main()
{
	std::auto_ptr<A>pa1(new A());
	pa1->print();
	cout<<"pa1 pointer: "<<pa1.get()<<endl;

	std::auto_ptr<A>pa2(pa1);	// copy constructor
	pa2->print();
	cout<<"pa1 pointer: "<<pa1.get()<<endl;
	cout<<"pa2 pointer: "<<pa2.get()<<endl;
	pa1->print();

	return 0;
}

上面的代码将类中的成员变量删除

运行结果:

可以看到上面的代码没有报错,原因是没有访问属于对象的成员变量,这个类也没有成员变量,而成员函数是所有对象共享的。

 

unique_ptr

替换了auto_ptr,不再允许将对象赋值、拷贝给另外一个对象

int main()
{
	unique_ptr<string> upt(new string("sbsb"));
	unique_ptr<string> upt1(upt); 
	return 0;
}

如下,不再允许拷贝、赋值

如上图也可以看到编译器是如何禁用拷贝和赋值的

就是再函数后面 加delete

shared_ptr

一句话解释:多个指针可以指向同一个对象,每多添加一个指针指向这个对象,该对象的count变量就++, 当count==0时,释放该对象

解决了auto_ptr 某个对象仅能由一个指针拥有的情况

class A
{
private:
	int _a;
public:
	A(int a){ _a=a; }
	void print(){ cout<<"A::print "<<this->_a<<endl; }
};

int main()
{
	shared_ptr<A>sp1(new A(1)); 
	sp1->print();
	cout<<"sp1 pointer:"<<sp1.get()<<endl;

	shared_ptr<A>sp2(sp1);	// copy constructor
	sp2->print();
	cout<<"sp1 pointer: "<<sp1.get()<<endl;
	cout<<"sp2 pointer: "<<sp2.get()<<endl;
	
	cout<<"count sp1:"<<sp1.use_count()<<endl;
	cout<<"count sp2:"<<sp2.use_count()<<endl;	

	return 0;
}

运行结果:

 

weak_ptr

是一种不控制对象声明周期的智能指针,其设计的目的是为了配合shared_ptr的工作,它只能从一个shared_ptr或另一个weak_ptr对象构造,它的构造和析构不会引起引用计数的增加或减少。

weak_ptr用于解决shared_ptr相互引用时的死锁问题

#include <iostream>
#include <memory>
using namespace std;

class B;
class A
{
public:
	shared_ptr<B> pb_;
	~A() { cout<<"~A()"<<endl; }
};

class B
{
public:
	shared_ptr<A> pa_;
	~B() { cout<<"~B()"<<endl; }
};

void fun()
{
	shared_ptr<B> pb(new B());
	shared_ptr<A> pa(new A());
	pb->pa_ = pa;
	pa->pb_ = pb;
	cout<<pb.use_count()<<endl;
	cout<<pa.use_count()<<endl;
}

int main()
{
	fun();
	return 0;
}

程序执行结果:

如图所示:两个智能指针的引用计数都为2,因为pb指向自己创建的对象,同时自己也被pa中的pb_指向, pa同理

当退出函数fun时,两个对象都调用析构函数,使其自身的引用计数--,但还是1,这时就造成了资源浪费

 

解决:将其中一个改为weak_ptr

因为资源B的引用计数值一直为1,当调用析构函数时,B的计数变为0,B释放的同时也会使A的计数减一。同时pa析构时使A的计数减一

那么A的计数为0,A得到释放

 

share_ptr 实现

(2条消息) C++面试题(四)——智能指针的原理和实现_算法的天空-CSDN博客_智能指针实现

template <typename T>
class SmartPointer {
public:
	//构造函数
	SmartPointer(T* p=0): _ptr(p), _reference_count(new size_t){
		if(p)
			*_reference_count = 1; 
		else
			*_reference_count = 0; 
	}
	//拷贝构造函数
	SmartPointer(const SmartPointer& src) {
		if(this!=&src) {
			_ptr = src._ptr;
			_reference_count = src._reference_count;
			(*_reference_count)++;
		}
	}
	//重载赋值操作符
	SmartPointer& operator=(const SmartPointer& src) {
		if(_ptr==src._ptr) {
			return *this;
		}
		releaseCount();
		_ptr = src._ptr;
		_reference_count = src._reference_count;
		(*_reference_count)++;
		return *this;
	}
 
	//重载操作符
	T& operator*() {
		if(ptr) {
			return *_ptr;
		}
		//throw exception
	}
	//重载操作符
	T* operator->() {
		if(ptr) {
			return _ptr;
		}
		//throw exception
	}
	//析构函数
	~SmartPointer() {
		if (--(*_reference_count) == 0) {
            delete _ptr;
            delete _reference_count;
        }
	}
private:
	T *_ptr;
        size_t *_reference_count;
        void releaseCount() {
		if(_ptr) {
			(*_reference_count)--;
    			if((*_reference_count)==0) {
    				delete _ptr;
    				delete _reference_count;
    			}
		}
    	}
};
 
int main() 
{
    SmartPointer<char> cp1(new char('a'));
    SmartPointer<char> cp2(cp1);
    SmartPointer<char> cp3;
    cp3 = cp2;
    cp3 = cp1;
    cp3 = cp3;
    SmartPointer<char> cp4(new char('b'));
    cp3 = cp4;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值