【C++编程】智能指针shared_ptr与unique_ptr
智能指针shared_ptr与unique_ptr
unique_ptr支持动态数组,而shared_ptr不能直接支持动态数组:
std::unique_ptr<int []> ptr(new int[10]); //合法,
std::shared_ptr<int []> ptr(new int[10]); //是不合法的
如果通过std::shared_ptr来构造动态数组,则需要显式指定删除器,比如下面的代码:
std::shared_ptr<int> p(new int[10], [](int* p){delete[] p;}); //指定delete[]
unique_ptr指定删除器的方法和std:: shared_ptr是有区别的:
std:: shared_ptr<int> ptr(new int(1), [](int*p){delete p;}); //正确
std::unique_ptr<int> ptr(new int(1), [](int*p){delete p;}); //错误
std::unique_ptr指定删除器的时候需要确定删除器的类型,所以不能直接像shared_ptr指定删除器,正确写法如下:
std::unique_ptr<int, void(*)(int*)> ptr(new int(1), [](int*p){delete p;});
上面这种写法在lambda没有捕获变量的情况下是正确的,如果捕获了变量则会编译报错:
std::unique_ptr<int, void(*)(int*)> ptr(new int(1), [&](int*p){delete p;}); //错误,因为捕获了变量
为什么lambda捕获了变量作为unique_ptr就会报错呢,因为lambda在没有捕获变量的情况下是可以直接转换为函数指针的,捕获了就不能转换为函数指针。如果希望unique_ptr的删除器支持lambda,可以这样写:
std::unique_ptr<int, std::function<void(int*)>> ptr(new int(1), [&](int*p){delete p;});
1. 使用lambda表达式
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int>(new int[5](), [](int *x) {
std::cout << "Delete function called" << std::endl;
delete[] x;
});
}
2. 使用普通函数
#include <iostream>
#include <memory>
void deleter(int *x) {
std::cout << "Delete function called" << std::endl;
delete[] x;
}
int main() {
std::shared_ptr<int>(new int[5](), deleter);
}
3.使用类重载:
#include <iostream>
#include <memory>
class Deleter {
public:
void operator()(int *x) {
std::cout << "Delete function called" << std::endl;
delete[] x;
}
};
int main() {
std::shared_ptr<int>(new int[5](), Deleter());
}
4. 使用std::default_delete:
#include <memory>
#include <vector>
#include <algorithm>
int main() {
{
std::shared_ptr<int> shared_good(new int[10], std::default_delete<int[]>());
}
std::vector<int *> v;
for (int n = 0; n < 100; ++n)
v.push_back(new int(n));
std::for_each(v.begin(), v.end(), std::default_delete<int>());
}
#include <iostream>
#include <memory>
struct Foo {
Foo() { std::cout << "Foo...\n"; }
~Foo() { std::cout << "~Foo...\n"; }
};
struct D {
void operator()(Foo *p) {
std::cout << "Calling delete for Foo object... \n";
delete p;
}
};
int main() {
std::cout << "Creating new Foo...\n";
//up owns the Foo pointer (deleter D)
std::unique_ptr<Foo, D> up(new Foo(), D());
std::cout << "Replace owned Foo with a new Foo...\n";
up.reset(new Foo()); // calls deleter for the old one
std::cout << "Release and delete the owned Foo...\n";
up.reset(nullptr);
}
输出:
Creating new Foo...
Foo...
Replace owned Foo with a new Foo...
Foo...
Calling delete for Foo object...
~Foo...
Release and delete the owned Foo...
Calling delete for Foo object...
~Foo...