C++与Qt的智能指针
·
大家好,我是⑩。
大家在学习C++或者QT的时候,总是会遇到内存泄漏的问题。就是如果忘记删除,或者删除的情况没有考虑清楚,容易造成悬挂指针(dangling pointer)或者说野指针(wild pointer)。
一:C++智能指针总类:shared_ptr unique_ptr weak_ptr。
1.shared_ptr:共享所有权指针,对资源做引用计数。
智能指针定义
shared_ptr<int> p = make_shared<int>(1);
shared_ptr<int> p2(p);
shared_ptr<int> p3 = p;
1.1shared_ptr需要维护的信息有两部分
- 指向共享资源的指针。
- 引用计数等共享资源的控制信息——实现上是维护一个指向控制信息的指针。
1.2手撕shared_ptr智能指针
// 简化实现
template<typename T>
class SharedPtr {
T* ptr;
int* count; // 引用计数
public:
SharedPtr(T* p) : ptr(p), count(new int(1)) {}
SharedPtr(const SharedPtr& other)
: ptr(other.ptr), count(other.count) {
++(*count); // 增加引用计数
}
~SharedPtr() {
if (--(*count) == 0) {
delete ptr;
delete count;
}
}
};
1.3shared_ptr引发的循环引用问题
struct Father
{
shared_ptr<Son> son_;
};
struct Son
{
shared_ptr<Father> father_;
};
int main()
{
auto father = make_shared<Father>();
auto son = make_shared<Son>();
father->son_ = son;
son->father_ = father;
return 0;
}
该部分代码会有内存泄漏问题。原因是
1.main 函数退出之前,Father 和 Son 对象的引用计数都是 2。
2.son 指针销毁,这时 Son 对象的引用计数是 1,father 指针销毁,这时 Father 对象的引用计数是 1。
1.4解决循环引用问题
3.由于两个智能指针的引用计数都不为0,导致循环引用的内存泄漏,这时就需要使用 weak_ptr。weak_ptr 并不拥有其指向的对象,也就是说,让 weak_ptr 指向 shared_ptr 所指向对象,对象的引用计数并不会增加。
struct Father
{
shared_ptr<Son> son_;
};
struct Son
{
weak_ptr<Father> father_;
};
int main()
{
auto father = make_shared<Father>();
auto son = make_shared<Son>();
father->son_ = son;
son->father_ = father;
return 0;
}
2.unique_ptr:独占所有权指针,不可拷贝,只可引用。
2.1使用unique_ptr自动管理内存
std::unique_ptr<int> uptr = std::make_unique<int>(200);
//...
// 离开 uptr 的作用域的时候自动释放内存
2.2只可引用,不可拷贝问题
std::unique_ptr utr=std::make_unique<int> 200;
std::unique_ptr utr1=utr;//编译错误,std::unique_ptr<T> 是 move-only 的。
std::unique_ptr utr2=std::move(utr);
assert(uptr == nullptr);
3.weak_ptr:弱引用智能指针,不增加引用计数,用于解决循环引用问题。
3.1一个 weak_ptr 对象看做是 std::shared_ptr 对象管理的资源的观察者,它不影响共享资源的生命周期。
二:QT智能指针总类:QSharedPointer QScopedPointer QWeakPointer
1.QSharedpointer:类似于std::shared_ptr,使用引用计数实现共享所有权。
2.QScopedPointer:类似于std::uniqued_ptr,是独占所有权的。当指针离开作用域时,它指向的对象会被自动删除。不能用于容器。
3.QScpoedPointer:似于std::weak_ptr,与QSharedPointer配合使用,解决循环引用问题。
更多推荐


所有评论(0)