RAII(Resource Acquisition Is Initialization:资源获取即初始化)
2017-05-18 17:02
495 查看
1.裸指针,操作不当导致,空悬指针(指针所指向的资源已经被释放,但是指针未置空),内存泄漏,重复释放
2.栈展开的过程中不会自动释放
3.应用RAII技巧,将裸指针换为智能指针(是一个类),将指针转为对象,对象的析构函数在生命周期结束的时候是确定被调用的
4.RAII(Resource Acquisition Is Initialization:资源获取即初始化)。一个对象可拥有资源。在对象的构造函数中执行资源的获取(指针的初始化),在析构函数中释放。
5.资源:内存,文件句柄,套接字,互斥量
2.栈展开的过程中不会自动释放
3.应用RAII技巧,将裸指针换为智能指针(是一个类),将指针转为对象,对象的析构函数在生命周期结束的时候是确定被调用的
4.RAII(Resource Acquisition Is Initialization:资源获取即初始化)。一个对象可拥有资源。在对象的构造函数中执行资源的获取(指针的初始化),在析构函数中释放。
5.资源:内存,文件句柄,套接字,互斥量
NodePtr.h #ifndef _NODEPTR_H_ #define _NODEPTR_H_ class Node { public: Node() { std::cout << "Node()"<< std::endl; } virtual ~Node() { std::cout << "~Node()"<< std::endl; } virtual void Calc() { std::cout << "Node::Calc()"<< std::endl; } }; class ChildNode: public Node { public: ChildNode() { std::cout << "ChildNode()"<< std::endl; } virtual ~ChildNode() override { std::cout << "~ChildNode()"<< std::endl; } virtual void Calc() { std::cout << "ChildNode::Calc()"<< std::endl; } }; template<typename T> class NodePtr { private: T* ptr_; public: explicit NodePtr(T* ptr=0):ptr_(ptr) {} NodePtr(NodePtr<T>& ptr):ptr_(ptr.Release()) {} //不同类之间,比如继承体系 template<typename U> NodePtr(NodePtr<U>& ptr):ptr_(ptr.Release()) {} NodePtr& operator=(NodePtr<T>& ptr) { Reset(ptr.Release()); return *this; } //不同类之间,比如继承体系 template<typename V> NodePtr& operator=(NodePtr<V>& ptr) { Reset(ptr.Release()); return *this; } template<typename _Other> operator NodePtr<_Other>() { return (NodePtr<_Other>(*this)); } ~NodePtr() { delete ptr_; ptr_ = NULL; } T* operator->() { //return ptr_; return &(operator*()); } T& operator*() { return *ptr_; } T* Get() const { return ptr_; } T* Release() { T* tmp = this->ptr_; ptr_ = NULL; return tmp; } void Reset(T* ptr) { if(ptr_ != ptr) { delete ptr_; } ptr_ = ptr; } }; #endif // _NODEPTR_H_ main.cpp #include <iostream> #include <memory> #include <vector> using namespace std; #include "DebugNew.h" #include "NodePtr.h" int main(void) { int* p = new int; //cout << p << endl; delete p; int* p2 = new int[5]; delete []p2; //Node* node = new Node; // 裸指针 // NodePtr<Node> ptr(new Node); // ptr->Calc(); // (*ptr).Calc(); // NodePtr<Node> ptr2(ptr); // NodePtr<Node> ptr3; // // ptr3 = ptr2; // // //ptr2->Calc(); // ptr3->Calc(); NodePtr<Node> ptr4(new ChildNode); //ptr4->Calc(); NodePtr<Node> ptr5(new ChildNode); //ptr5->Calc(); ptr4 = ptr5; if(NULL == ptr5.Get()) { cout << "ptr5 is NULL " << endl; } //ptr4->Calc(); std::auto_ptr<Node> node(new Node); vector<std::auto_ptr<Node>> v; //v.push_back(v); /* 1.auto_ptr不能作为STL容器元素 2.STL容器要求存放在容器中的元素是值语义 3.auto_ptr的拷贝构造或者赋值操作 会改变 有操作数, 因为有操作数的所有权要发生转移 */ return 0; } /* 合理地使用智能指针,就能够保证编码不内存泄漏C++代码 std::vector<Node*> childs_; void AppendChild() { childs_.push_back(node.release()); } 指针所有权释放了 vector 保存的是指针本身,并没有保存指针所指向的内存 vector 不负责指针所指向内存管理 vector 内部至少要分配4个字节的内存,才够存放 现代操作系统都支持虚拟内存 要插入的裸指针还没插入到vector, 概率低 vector析构的时候,是否会释放所指向的内存呢,他只负责指针变量本身 std::auto<Node> node(new Node); vector<std::autor<Node> > v; v.push_back(node); STL容器要求存放在容器中的元素能够被拷贝,也就是要求类型是值语义对象 auto_ptr就是值语义 实际上是对象语义 转化为值语义 解决方法:可以采用其他类型的智能指针,shared_ptr, scoped_ptr boost库,ptr_container, ptr_vector指针容器 */ //new(__FILE__, __LINE__) int
相关文章推荐
- RAII(Resource Acquisition Is Initialization资源获取即初始化 )思想
- RAII(Resource Acquisition Is Initialization)资源获得式初始化
- RAII:资源获取即初始化(resourse acquisition is initialization)
- 浅谈----RAII资源获得即初始化(Resource Acquisition Is Initialization)
- Resource Acquisition Is Initialization(RAII Idiom)
- Resource Acquisition Is Initialization(RAII Idiom)
- Resource Acquisition Is Initialization(RAII Idiom)
- Resource Acquisition Is Initialization(RAII)
- Resource Acquisition Is Initialization (RAII)是什么?(封装的优势)
- RAII -- Resource Acquisition Is Initialization
- The RAII(resource acquisition is initialization) of C++
- RAII (Resource Acquirement Is Initialization)
- RAII:资源获取即初始化
- RAII,也称为“资源获取就是初始化”
- C++必知必会 - RAII(资源获取及初始化)
- C++ “resource acquisition is initialization”
- RAII-获取资源即初始化
- 资源获取即初始化【RAII】
- RAII技术--获取资源即初始化
- 资源获取即初始化RAII