佳能6780 G1810 TS5060 5080 6020喷墨打印机进入维修模式方法

A邱凌

关注

阅读 75

2024-11-09

unique_ptr 独占智能指针。
它独占指向的对象,也就是说,某个时刻只有一个 unique_ptr 指向一个给定对象,当unique_ptr 被销毁时,它所指向的对象也被销毁,
需要包含头文件:

#include <memory>

1.类定义:

以下是unique_str的部分源码

template< class T,class Del=default delete<T>>
class unique ptr {
public:
unique_ptr( );    //默认构造函数
explicit unique_ptr( pointer Ptr);//构造函数,不允许隐式转换
unique_ptr (pointer Ptr, typename remove_reference<Del>::type&& Deleter)
unique ptr(const unique_ptr& Right)= delete;//不允许拷贝构造
unique ptr& operator=(const unique ptr& Right )= delete;//不允许赋值
};

说明:unique_ptr是"唯一"类型的智能指针,不允许多个智能指针指向同一个对象。因此不支持 = 和 拷贝构造。

2.初始化:

//方法
unique_ptr<student>p1(new student("刘备"));// 分配内存并初始化。
//方法二:
unique_ptr<Student>p2 = make unique<student>("曹操");//C++14标准提供,优先使用
//方法三:
Student* ps = new student("孙权");
unique_ptr<student>p3(ps);//用已存在的地址初始化。

例如:

class Student{
public:
Student(const string& name =""):m name(name)//构造函数
{
cout<<"构造函数:"<<m name<<",被创建"<<endl;
}
~Student()
{
cout<<"析构函数:"<<m name <<",被释放了"<<endl;
}
void show() const
{
cout<<"学生名字:"<<m name << endl;
}
private:
string m_name;//学生姓名
};
int main()
{
//方法
unique_ptr<student>p1(new student("刘备"));//分配内存并初始化,常用
//方法二:
unique_ptr<Student>p2 = make_unique<student>("曹操");//c++14标准,常用
//方法三:
Student* ps = new student("孙权");
unique_ptr<student>p3(ps);//用已存在的地址初始化,不常用(容易出错,下面有示例)
//unique ptr<student>p4;
//p4 = p1;//错误,不能赋值 =
//unique_ptr<student>p5(p1);//错误不能使用拷贝构造
return 0;
}

当智能指针的生命周期结束时,会自动调用对应的析构函数。
警告:不要用同一个指针,初始化多个智能指针对象。

错误示例:

//错误代码演示
int main()
{
Student* p1 = new student(“趣字节”);
unique_ptr<student>p2(p1);
unique_ptr<student>p3(p1);
return 0;
}

3.成员函数

get:获取源指针

int main()
{
Student* p1 = new student("刘备");
unique_ptr<student>p2(p1);
cout<<"刘备的地址:"<<p1<<endl;
cout<<"刘备的地址:"<< p2 << endl;
cout<<"刘备的地址:"<<p2.get()<< endl;;
cout<<"智能指针对象的地址:"<<&p2<< endl;
return 0;
}

release
返回源指针,unique ptr放弃对源指针的控制权,并被置空。下面的示例演示get和release的使用。

//需要一个student指针,不负责释放内存
void test01(const student* ps)
{
ps->show();
}
//需要一个student指针,且负责释放内存
void teste2(student* ps)
{
ps->show();
delete ps;
}
//最常用.需要一个unique ptr指针,不负责释放内存
void test03(const unique_ptr<student>&p)
{
p->show();
}
//需要一个unique_ptr指针(非引用),不建议这样使用
void test04(const unique ptr<student>p)
{
p->show();
}
int main()
{
unique_ptr<student> p(new student("赵云"));
cout<<"开始调用函数-------"<< endl;
test01(p.get());//get成员函数,返回源指针
test02(p.release());//release成员函数,返回源指针并释放控制权
if(p == nullptr)
cout<<"p已经为空"<< endl;
p= make_unique<student>("马超");//上面的p已经被释放,重新创建马超
test03(p);//最正常的使用
//test04(p);//错误,不支持拷贝构造函数
test04(move(p));//std::move 移动拷贝
cout<<"所数调用结束-------"<< endl:
return 0;
}

reset
重置。 释放当前拥有的对象,同时指向新的对象。

p.reset();//释放p指向的对象(内存)
p.reset(new student("孙尚香"));//释放p指向的对象(内存)

swap
交换两个unique_ptr。

int main()
{
auto p1 = make_unique<student>("关羽");
auto p2 = make unique<student>("张飞");
cout<<"p1:";p1->show();
cout<<"p2:";p2->show();
p1.swap(p2);
cout<<"交换后-"<<endl;
cout<<"p1:";p1->show(),
cout<<"p2:";p2->show();
return 0;
}

4.作为函数参数

传引用。不能传值(因为unique_ptr没有拷贝构造函数)

void test(const unique ptr<student>& p)
{

cout <<"test函数"<<endl;
p->show();
}
int main()
{
unique_ptr<student> p1(new student("曹操"));
test(p1);
return 0;
}

5.作为函数返回值(了解)
unique ptr不能复制有一个例外,就是从函数返回一个unique ptr(这个操作内部使用的是移动赋值,移动赋值并没有被禁用)。

unique_ptr<student>test02()//返回一个智能指针
{
return make unique<student>("孙权");
}
int main()
{
//auto p=test02();//接收一个智能指针.下面两行等同这一行
unique_ptr<student> p;
p = test02();
p->show();
return 0;
}

如果智能指针原来有值,那么在接受函数返回值后,原来的对象会被释放。

如果智能指针原来有值,在被赋值为nullptr后,原来的对象会被释放。

6.作为数组

int main()
{
Student* p1 = new student[2]{student("刘备"),student("曹操")};//普通的动态数组
p1[0].show();
p1[1].show();
delete[]p1;//释放动态数组
cout << endl;
unique_ptr<student[]>p2(new student[2]{ student("孙权"),student("周瑜")});//智能指针
//unique_ptr<student[l>p2(new student[21);
p2[0].show();
p2[1].show();
return 0;
}

注意,创建数组时<>中有个中括号[]表示数组

7. 用于类继承(了解)
unique ptr也可以指向基类对象,也具有多态性质。

unique_ptr<A>p2= make_unique<A>();//创建智能指针,指向基类对象
p2->Show();//调用基类对象的成员函数
//不用调用delete
p2 = make_unique<B>();//指向子类对象
p2->show();//调用子类对象的成员函数
//不用调用delete

8. 添加删除器(面试可能问)
可以通过函数,仿函数,lambda表达式,自定义删除器。

//自定义删除器,普通函数
void DeleteFunc(student* ps)
{
cout<<"自定义删除器(普通函数)"<< endl;
delete ps;//如果漏写这句就可能出现内存泄漏,但这是你的代码问题,不是智能指针问题
}
//白定义删除器,仿函数
class Deleteclass
{
public:
void operator()(student*ps)//重载()
{
cout<<"自定义删除器(仿函数)"<<endl;
delete ps;

}
};
//自定义删除器,lambda
auto DeleteLambda=Student* ps)
{
cout<<"自定义删除器(lambda)"<< endl;
delete ps;
}
int main()
{
//自定义删除器,普通函数
unique_ptr<Student,decltype(DeleteFunc)*> p1(new student("刘备"),DeleteFunc);
//自定义删除器,仿函数
unigue_ptr<Student, Deleteclass> p2(new student("曹操"),Deleteclass());
//自定义删除器,lambda
unique_ptr<Student, decltype(DeleteLambda)> p3(new student("孙权"),DeleteLambda);
return 0;
}

精彩评论(0)

0 0 举报