C++ 使用智能指针会出现什么问题?怎么解决?

发布于 2023-09-14 12:26:45 字数 3157 浏览 27 评论 0

智能指针可能出现的问题:循环引用

在如下例子中定义了两个类 Parent、Child,在两个类中分别定义另一个类的对象的共享指针,由于在程序结束后,两个指针相互指向对方的内存空间,导致内存无法释放。

#include <iostream>
#include <memory>

using namespace std;

class Child;
class Parent;

class Parent {
 private:
  shared_ptr<Child> ChildPtr;

 public:
  void setChild(shared_ptr<Child> child) { this->ChildPtr = child; }

  void doSomething() {
    if (this->ChildPtr.use_count()) {
    }
  }

  ~Parent() {}
};

class Child {
 private:
  shared_ptr<Parent> ParentPtr;

 public:
  void setPartent(shared_ptr<Parent> parent) { this->ParentPtr = parent; }
  void doSomething() {
    if (this->ParentPtr.use_count()) {
    }
  }
  ~Child() {}
};

int main() {
  weak_ptr<Parent> wpp;
  weak_ptr<Child> wpc;
  {
    shared_ptr<Parent> p(new Parent);
    shared_ptr<Child> c(new Child);
    p->setChild(c);
    c->setPartent(p);
    wpp = p;
    wpc = c;
    cout << p.use_count() << endl;  // 2
    cout << c.use_count() << endl;  // 2
  }
  cout << wpp.use_count() << endl;  // 1
  cout << wpc.use_count() << endl;  // 1
  return 0;
}

循环引用的解决方法: weak_ptr

循环引用:该被调用的析构函数没有被调用,从而出现了内存泄漏。

weak_ptr 对被 shared_ptr 管理的对象存在非拥有性(弱)引用,在访问所引用的对象前必须先转化为 shared_ptr;

weak_ptr 用来打断 shared_ptr 所管理对象的循环引用问题,若这种环被孤立(没有指向环中的外部共享指针),shared_ptr 引用计数无法抵达 0,内存被泄露;令环中的指针之一为弱指针可以避免该情况;

weak_ptr 用来表达临时所有权的概念,当某个对象只有存在时才需要被访问,而且随时可能被他人删除,可以用 weak_ptr 跟踪该对象;需要获得所有权时将其转化为 shared_ptr,此时如果原来的 shared_ptr 被销毁,则该对象的生命期被延长至这个临时的 shared_ptr 同样被销毁。

#include <iostream>
#include <memory>

using namespace std;

class Child;
class Parent;

class Parent {
 private:
  // shared_ptr<Child> ChildPtr;
  weak_ptr<Child> ChildPtr;

 public:
  void setChild(shared_ptr<Child> child) { this->ChildPtr = child; }

  void doSomething() {
    // new shared_ptr
    if (this->ChildPtr.lock()) {
    }
  }

  ~Parent() {}
};

class Child {
 private:
  shared_ptr<Parent> ParentPtr;

 public:
  void setPartent(shared_ptr<Parent> parent) { this->ParentPtr = parent; }
  void doSomething() {
    if (this->ParentPtr.use_count()) {
    }
  }
  ~Child() {}
};

int main() {
  weak_ptr<Parent> wpp;
  weak_ptr<Child> wpc;
  {
    shared_ptr<Parent> p(new Parent);
    shared_ptr<Child> c(new Child);
    p->setChild(c);
    c->setPartent(p);
    wpp = p;
    wpc = c;
    cout << p.use_count() << endl;  // 2
    cout << c.use_count() << endl;  // 1
  }
  cout << wpp.use_count() << endl;  // 0
  cout << wpc.use_count() << endl;  // 0
  return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

0 文章
0 评论
737 人气
更多

推荐作者

金兰素衣

文章 0 评论 0

ゃ人海孤独症

文章 0 评论 0

一枫情书

文章 0 评论 0

清晰传感

文章 0 评论 0

mb_XvqQsWhl

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文