c++shared_ptr用enable_shared_from_this从this转换到shared_ptr(C++类相关)
·
类的内部需要调用自己的智能指针时this智能指针难以传入,出了作用域会调用析构
所以伪造一个智能指针来传this是错误的,他会管理同样一份资源调用两次析构
需要把自己作为智能指针传入,调用的时候应该用奇异模板递归(CRTP)
class Parent : public std::enable_shared_from_this<Parent> {
public:
WeakChildPtr son;
~Parent();
Parent();
void checkRelation();
};
void Parent::checkRelation() {
auto ps = son.lock();
if(ps) {
// this
handleChildAndParent(shared_from_this(), ps);
}
std::cout << "after call checkRelation\n";
}
以下是完整代码:
#include <cassert>
#include <memory>
#include <iostream>
// auto_ptr
// shared_ptr
// enable_shared_from_this // CRTP
// weak_ptr
// unique_ptr
void sharedPtrNotice();
class Parent;
typedef std::shared_ptr<Parent> ParentPtr;
typedef std::weak_ptr<Parent> WeakParentPtr;
class Child : public std::enable_shared_from_this<Child> {
public:
WeakParentPtr father;
~Child();
Child();
void checkRelation();
};
typedef std::shared_ptr<Child> ChildPtr;
typedef std::weak_ptr<Child> WeakChildPtr;
class Parent : public std::enable_shared_from_this<Parent> {
public:
WeakChildPtr son;
~Parent();
Parent();
void checkRelation();
};
void handleChildAndParentRef(const Parent& p, const Child& c) {
auto cp = c.father.lock();
auto pc = p.son.lock();
if(cp.get() == &p && pc.get() == &c) {
std::cout << "right relation\n";
} else {
std::cout << "oop!!!!!\n";
}
}
void handleChildAndParent(const ParentPtr& p, const ChildPtr& c) {
auto cp = c->father.lock();
auto pc = p->son.lock();
if(cp == p && pc == c) {
std::cout << "right relation\n";
} else {
std::cout << "oop!!!!!\n";
}
}
Child::Child() { std::cout << "hello child\n";}
Parent::Parent() { std::cout << "hello parent\n";}
Child::~Child() { std::cout << "bye child\n";}
Parent::~Parent() { std::cout << "bye parent\n";}
void Parent::checkRelation() {
auto ps = son.lock();
if(ps) {
// this
handleChildAndParent(shared_from_this(), ps);
}
std::cout << "after call checkRelation\n";
}
void Child::checkRelation() {
// we call handleChildAndParent
}
void testParentAndChild() {
Parent pp;
ParentPtr p(new Parent());
ChildPtr c(new Child());
p->son = c; // c.use_count() == 2 and p.use_count() == 1
c->father = p; // c.use_count() == 2 p.use_count() == 2
p->checkRelation();
}
static void interfaceOfSharedPtr();
static void sharedPtrWithWeakPtr();
static void uniquePtr();
int main() {
testParentAndChild();
// interfaceOfSharedPtr();
// sharedPtrWithWeakPtr();
// uniquePtr();
}
更多推荐
所有评论(0)