常用的智能指针就是shared_ptr;要注意他初始化时不能进行隐式类型转换;

shared_ptr和new结合使用;

接收指针参数的智能指针构造函数是explicit的,没有explicit时被称为转换函数,将进行自动类型转换,有了explicit后将不能进行自动类型转换,必须进行强制类型转换;

shared_ptr<int>p1=new int(42);不能进行int*到shared_ptr<int>的转换,

相应的只能使用直接初始化的方式:shared_ptr<int>p2(new int(31));

因此返回值为shared_ptr<typename>的函数必须调用shared_ptr<typename>()或者make_shared<T>();或者返回一个已经存在的shared_ptr<ptr>;

shared_ptr的初始化:参数要么时内置类型指针,要么是智能指针,前者必须通过构造函数或者make_shared<T>(args),使用构造函数时参数只能是(p)进行赋值

归纳:一般推荐make_shared<T>(args);

不要混合使用普通指针和智能指针;

推荐使用make_shared<T>(args)来初始化智能指针,使用new将会导致同一块内存绑定到多个独立创建的智能指针上,这就会导致内存被delete;

p.get()返回一个内置的指针类型,指向p所指向的内存空间,当使用内置指针类型和智能指针类型相互赋值时很容易出现问题;

void process(shared_ptr<int>ptr)
{
//使用ptr
}//离开,ptr被销毁;
实参传给形参值时,计数器递增一次,ptr销毁时减少一次;但计数器不会为0,因为实参没有被销毁,即不被销毁的前提是实参不是临时变量;

shared_ptr<int>p(new int (42));

process(p);

int i=*p;
没有问题;

int*x(new int(42));如果x是shared_ptr类型就没问题;
process(shared_ptr<int>(x));实参是临时对象,赋值完成后就会被销毁;当ptr也被销毁时,x指向的
内存空间就被释放;
int j=*x;

因此当我们将一个shared_ptr绑定到一个普通指针时,就不能再使用普通指针访问智能指针的内存了,否则就会出问题,即普通指针智能作为参数一次;

也不要使用get()初始化一个智能指针或为智能指针赋值;

总之,一块内存不能被绑定到多个独立创建的shared_ptr上,造成多个绑定的原因就是使用new和普通指针来初始化shared_ptr;即应该防止普通指针指向智能指针的内存空间;

智能指针和异常

函数的退出,无论正常结束还是异常,局部对象都会被销毁,智能指针指向的内存都会被释放;但是内置指针指向的内存在发生异常时是不会被释放的,

此外有些类的析构函数不能很好的释放内存或者资源,也会导致内存或资源的泄漏;

因此,使用shared_ptr保证各种资源不会泄露是有效的方法,这要自己定义delete操作,即释放资源的操作;默认情况下,shared_ptr假定他们指向的是动态内存,当一个shared_ptr被销毁时,它默认对它的指针指向的资源进行释放操作,默认情况下是内存,如果是别的资源,就必须定义一个函数来代替delete,这个删除器必须完成对shared_ptr的释放操作;

struct destination;
struct connection;
connection connect(destination*);
void disconnect(connection);

void end_connection(connection*p){disconnect(*p);}

connection c=connect(&d);
shared_ptr<connection>p(&c,end_connection);

unique_ptr

 

07-15 11:52