内存问题永远是c++中讨论的重要话题
1.c98 auto_ptr的实现,auto_ptr的特点是始终只保持一个指针指向对象,若经过赋值或者拷贝之后原指针失效
#include <iostream> using namespace std; template<typename T> class auto_ptr { public: explicit auto_ptr(T* px = 0):m_px(px){} auto_ptr(const auto_ptr& rhs):m_px(rhs.release()) { } auto_ptr& operator=(auto_ptr& rhs) { reset(rhs.release()); return *this; } T* get() { return m_px; } T& operator*() { return *m_px; } T* operator->() { return m_px; } T* release() { T* temp = m_px; m_px = 0; return temp; } T* reset(T* px) { delete m_px; m_px = ptr; }
~ auto_ptr(){delete m_px;} private: T *m_px; }; int main() { return 0; }
2.boost库里的scoped_ptr和auto_ptr实现方式相同,不同点是scoped_ptr禁止赋值和拷贝。相同的缺点是可以返回原始指针,但是会让对象脱离智能指针的控制。、
scoped_ptr和auto_ptr都不能用作容器,原因不一样,auto_ptr转移语义,scoped_ptr则禁止复制。
3.shared_ptr是boost里最重要的指针,实现比auto_ptr要复杂的多,采用了引用计数和成员函数模板
下面说说shared_ptr存在的问题,
3.1.这个问题也是多线程存在的问题,线程安全,会进行重复析构。
#include <iostream> #include <boost/shared_ptr.hpp> using namespace std; using namespace boost; int main() { string *pstr = new string("test program"); { shared_ptr<string> sp1(pstr); cout << sp1->size() <<endl; } shared_ptr<string> sp2(pstr); cout << sp2->size() <<endl; return 0; }
3.2循环引用,循环引用会造成内存泄漏,解决办法是将这种强引用关系转为弱引用关系,其中的一个成员变量使用weak_ptr<Parent> m_parent;
#include <iostream> #include <boost/shared_ptr.hpp> using namespace std; using namespace boost; class Parent; class Children; typedef boost::shared_ptr<Parent> parent_ptr; typedef boost::shared_ptr<Children> children_ptr; class Parent { public: children_ptr m_children; }; class Children { public: parent_ptr m_parent; }; int main() { parent_ptr parent(new Parent); children_ptr children(new Children); parent->m_children = children; children->m_parent = parent; return 0; }