/* 智能指针unique_ptr */
#include <iostream>
#include <string>
#include <memory>
#include <vector>
/*
unique_ptr 独占所指向的对象, 同一时刻只能有一个 unique_ptr 指向给定对象(通过禁止拷贝语义, 只有移动语义来实现),
定义于 memory (非memory.h)中, 命名空间为 std.
unique_ptr 不支持拷贝和赋值.
*/
struct Student
{
public:
Student(std::string name_, int age_) :name(name_), age(age_) {}
std::string name;
int age;
};
std::unique_ptr<Student> test_clone()
{
std::unique_ptr<Student> up1 = std::make_unique<Student>("spaow",65);
return up1;
}
struct STDeleter
{
void operator() (int* obj)
{
if (obj)
{
for (int i = 0; i < 10; i++)
{
//obj[i] = i + 2;
printf("obj[i] = %d\n", obj[i]);
}
free(obj);
obj = NULL;
}
}
};
void test()
{
//初始化方式一
std::unique_ptr<Student> up1 = std::make_unique<Student>("tom",11);
//error unique_ptr 不支持拷贝构造函数
//std::unique_ptr<Student> up2(up1);
//error unique_ptr 不支持赋值
//std::unique_ptr<Student> up3 = up1;
//初始化方式二
std::unique_ptr<Student> up4(new Student("jack", 10));
//初始化方式三:
/*
release方法: 放弃内部对象的所有权,将内部指针置为空, 返回所内部对象的指针, 此指针需要手动释放
*/
std::unique_ptr<Student> up5(up1.release());
//初始化方式四
/*
reset方法: 销毁内部对象并接受新的对象的所有权(如果使用缺省参数的话,也就是没有任何对象的所有权, 此时仅将内部对象释放, 并置为空)
*/
std::unique_ptr<Student> up6;
up6.reset(new Student("als", 12));
//成员函数的使用
//可以进行移动构造和移动赋值操作
std::unique_ptr<Student> up7;
up7 = std::move(up6);
std::unique_ptr<Student> up8(std::move(up7));
//特殊的拷贝
std::unique_ptr<Student> up9 = test_clone();
printf("name is [%s] .\n",up9->name.c_str());
//在容器中保存指针
std::vector<std::unique_ptr<Student> > vec;
std::unique_ptr<Student> upTmp(new Student("kld",16));
vec.push_back(std::move(upTmp));
//unique_ptr 支持管理数组
std::unique_ptr<int[]> ups(new int[10]);
printf("sizeof(ups) = %d\n", sizeof(ups));//打印4,并非数组实际长度
for (int i = 0; i < 10; i++)
{
ups[i] = i;
printf("ups[i] = %d\n", ups[i]);
}
//自定义删除器定义
int *tempArr = (int *)malloc(sizeof(int) * 10);
std::unique_ptr<int, STDeleter> usp2(tempArr, STDeleter());
int *pcIndex = usp2.get();
for (int i = 0; i < 10; i++)
{
pcIndex[i] = i+2;
}
}
int main()
{
test();
getchar();
return 0;
}