有一个需求,在std::function对象还未析构之前,释放掉其中绑定的智能指针?
使用std::function的成员函数swap,或者直接调用std::function的析构函数。
#include <functional>
#include <memory>
#include <iostream>
class ClassTest
{
public:
ClassTest()
{
std::cout << "Constrcut ClassTest\n";
}
~ClassTest()
{
std::cout << "Destruct ClassTest\n";
}
};
using ClassTestPtr = std::shared_ptr<ClassTest>;
using Func = std::function<void(ClassTestPtr)>;
void TestFunc(ClassTestPtr pClassTest)
{
}
情形1:
pFunc持有ClassTestPtr,在函数结束时,pFunc析构,释放ClassTestPtr,其引用计数变为0,然后再析构ClassTest。
int main()
{
Func pFunc;
std::cout << (pFunc ? "Callable\n" : "Not Callable\n");
std::cout << "Bracket Begin\n";
{
auto pClassTest = std::make_shared<ClassTest>();
pFunc = std::bind(TestFunc, pClassTest);
}
std::cout << "Bracket End\n";
std::cout << (pFunc ? "Callable\n" : "Not Callable\n");
return 0;
}
输出为:
Not Callable
Bracket Begin
Constrcut ClassTest
Bracket End
Callable
Destruct ClassTest
情形2:
pFunc.swap(Func())会交换pFunc对象和由Func()产生的临时对象中的可调用对象,该临时对象不包含任何可调用对象,交换后pFunc不持有可调用对象,临时对象持有pFunc原来的可调用对象。然后临时对象立即析构,释放掉持有的可调用对象。
int main()
{
Func pFunc;
std::cout << (pFunc ? "Callable\n" : "Not Callable\n");
std::cout << "Bracket Begin\n";
{
auto pClassTest = std::make_shared<ClassTest>();
pFunc = std::bind(TestFunc, pClassTest);
pFunc.swap(Func()); // pFunc.~function();效果一样
}
std::cout << (pFunc ? "Callable\n" : "Not Callable\n");
std::cout << "Bracket End\n";
return 0;
}
输出为
Not Callable
Bracket Begin
Constrcut ClassTest
Destruct ClassTest
Not Callable
Bracket End