The C++ Standard Library之auto_ptr
2013-12-12 18:20
246 查看
auto_ptr,可以联想 c的alloca()。alloca和auto_ptr只有自动释放的共性。
p40
a. auto_ptr 是這樣一種指標:它是「它所指向的物件」的擁有者(owner)。
auto_ptr 要求,一個物件只能有一個擁有者,嚴禁一物二主。
b. auto_ptr是区域变数,无论是正常退出,还是异常退出,只要函式退出,就一定会被销毁。
无论何种情况下,auto_ptr被销毁,就一定连带释放其所指资源。
c. 絕對不應該出現多個auto_ptrs 同時擁有一個物件的情況。不幸的是,這種事情可能會發生
(如果你以同一個物件為初值,將兩個 auto_ptr s 初始化,就會出現這種事)。程式員必須負責防範這種錯誤。
d. auto_ptr 的copy 建構式和assignment運算子將物件擁有權交出去。
擁有者一旦交出擁有權,就兩手空空,只剩一個null指標在手了。
//注意
e. 使用auto_ptr,要清楚是否需要交接拥有权和拥有权交接点。
f. auto_ptr 的語義本身就涵蓋擁有權,所以如果你無意轉交你的擁有權,就不要在參數列中使用auto_ptr ,也不要以它作爲回返值。
//bad example
std::auto_ptr<int> p(new int);
*p = 42; // change value to which p refers
bad_print(p); // Oops, deletes the memory to which p refers
*p = 18; // RUNTIME ERROR
const std::auto_ptr<int> p(new int); //p44
總而言之,常數型auto_ptr 減小了「不經意轉移擁有權」所帶來的危險。只要一個物件藉由auto_ptr 傳遞,就可以使用常數型auto_ptr
來終結擁有權移轉鏈,此後擁有權將不能再進行移轉。
關鍵字const 並非意味你不能更改auto_ptr 所擁有的物件,而是意味你不能更改auto_ptr 的擁有權。
g. 將auto_ptr s 以pass by reference 方式傳遞就萬事大吉。然而這種行爲卻會使「擁有權」的概念變得難以捉摸,因爲面對一個「透過reference 而
獲得auto_ptr 」的函式,你根本無法預知擁有權是否被轉交。所以以 by reference方式傳遞auto_ptr 是非常糟糕的設計,應該全力避免。
p46 auto_ptr的4个错误运用,详见原文。
autoptr.hpp
main.cpp
p40
a. auto_ptr 是這樣一種指標:它是「它所指向的物件」的擁有者(owner)。
auto_ptr 要求,一個物件只能有一個擁有者,嚴禁一物二主。
b. auto_ptr是区域变数,无论是正常退出,还是异常退出,只要函式退出,就一定会被销毁。
无论何种情况下,auto_ptr被销毁,就一定连带释放其所指资源。
c. 絕對不應該出現多個auto_ptrs 同時擁有一個物件的情況。不幸的是,這種事情可能會發生
(如果你以同一個物件為初值,將兩個 auto_ptr s 初始化,就會出現這種事)。程式員必須負責防範這種錯誤。
d. auto_ptr 的copy 建構式和assignment運算子將物件擁有權交出去。
擁有者一旦交出擁有權,就兩手空空,只剩一個null指標在手了。
//注意
e. 使用auto_ptr,要清楚是否需要交接拥有权和拥有权交接点。
f. auto_ptr 的語義本身就涵蓋擁有權,所以如果你無意轉交你的擁有權,就不要在參數列中使用auto_ptr ,也不要以它作爲回返值。
//bad example
std::auto_ptr<int> p(new int);
*p = 42; // change value to which p refers
bad_print(p); // Oops, deletes the memory to which p refers
*p = 18; // RUNTIME ERROR
const std::auto_ptr<int> p(new int); //p44
總而言之,常數型auto_ptr 減小了「不經意轉移擁有權」所帶來的危險。只要一個物件藉由auto_ptr 傳遞,就可以使用常數型auto_ptr
來終結擁有權移轉鏈,此後擁有權將不能再進行移轉。
關鍵字const 並非意味你不能更改auto_ptr 所擁有的物件,而是意味你不能更改auto_ptr 的擁有權。
g. 將auto_ptr s 以pass by reference 方式傳遞就萬事大吉。然而這種行爲卻會使「擁有權」的概念變得難以捉摸,因爲面對一個「透過reference 而
獲得auto_ptr 」的函式,你根本無法預知擁有權是否被轉交。所以以 by reference方式傳遞auto_ptr 是非常糟糕的設計,應該全力避免。
p46 auto_ptr的4个错误运用,详见原文。
autoptr.hpp
/* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * Permission to copy, use, modify, sell and distribute this software * is granted provided this copyright notice appears in all copies. * This software is provided "as is" without express or implied * warranty, and with no claim as to its suitability for any purpose. */ /* class auto_ptr * - improved standard conforming implementation */ namespace std { // auxiliary type to enable copies and assignments (now global) template<class Y> struct auto_ptr_ref { Y* yp; auto_ptr_ref (Y* rhs) : yp(rhs) { } }; template<class T> class auto_ptr { private: T* ap; // refers to the actual owned object (if any) public: typedef T element_type; // constructor explicit auto_ptr (T* ptr = 0) throw() : ap(ptr) { cout << "explicit auto_ptr() excute..." << endl; if(ptr) { cout << "explicit auto_ptr() *ap:" << *ptr << endl; } } // copy constructors (with implicit conversion) // - note: nonconstant parameter auto_ptr (auto_ptr& rhs) throw() : ap(rhs.release()) { cout << "auto_ptr (auto_ptr& rhs) excute..." << endl; } template<class Y> auto_ptr (auto_ptr<Y>& rhs) throw() : ap(rhs.release()) { cout << "auto_ptr (auto_ptr<Y>& rhs) excute..." << endl; } // assignments (with implicit conversion) // - note: nonconstant parameter auto_ptr& operator= (auto_ptr& rhs) throw() { cout << "operator= (auto_ptr& rhs) excute..." << endl; reset(rhs.release()); return *this; } template<class Y> auto_ptr& operator= (auto_ptr<Y>& rhs) throw() { cout << "operator= (auto_ptr<Y>& rhs) excute..." << endl; reset(rhs.release()); return *this; } // destructor ~auto_ptr() throw() { delete ap; } // value access T* get() const throw() { return ap; } T& operator*() const throw() { cout << "operator*() excute..." << endl; return *ap; } T* operator->() const throw() { return ap; } // release ownership T* release() throw() { T* tmp(ap); ap = 0; return tmp; } // reset value void reset (T* ptr=0) throw() { if (ap != ptr) { delete ap; ap = ptr; } } /* special conversions with auxiliary type to enable copies and assignments */ auto_ptr(auto_ptr_ref<T> rhs) throw() : ap(rhs.yp) { cout << "auto_ptr(auto_ptr_ref<T> rhs) excute..." << endl; } auto_ptr& operator= (auto_ptr_ref<T> rhs) throw() { // new reset(rhs.yp); return *this; } template<class Y> operator auto_ptr_ref<Y>() throw() { return auto_ptr_ref<Y>(release()); } template<class Y> operator auto_ptr<Y>() throw() { return auto_ptr<Y>(release()); } }; }
main.cpp
/* The following code example is taken from the book * "The C++ Standard Library - A Tutorial and Reference" * by Nicolai M. Josuttis, Addison-Wesley, 1999 * * (C) Copyright Nicolai M. Josuttis 1999. * Permission to copy, use, modify, sell and distribute this software * is granted provided this copyright notice appears in all copies. * This software is provided "as is" without express or implied * warranty, and with no claim as to its suitability for any purpose. */ #include <iostream> //#include <memory> #include "autoptr.hpp" using namespace std; /* define output operator for auto_ptr * - print object value or NULL */ #if 0 //test 1,允许转移,且有转移 ostream& operator<< (ostream& strm, auto_ptr<T>& p) { ...... auto_ptr<T> tmp = p; } //test 2,不允许转移,但有转移 ostream& operator<< (ostream& strm, const auto_ptr<T>& p) { ...... auto_ptr<T> tmp = p; } #endif template <class T> ostream& operator<< (ostream& strm, const auto_ptr<T>& p) { // does p own an object ? if (p.get() == NULL) { strm << "NULL"; // NO: print NULL } else { strm << *p; // YES: print the object } //auto_ptr<T> tmp = p; return strm; } int main() { auto_ptr<int> r(new int(43)); auto_ptr<int> s = r; //copy constructor cout << "##############" << endl << endl; auto_ptr<int> p(new int(42)); auto_ptr<int> q; cout << "after initialization:" << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; q = p; cout << "after assigning auto pointers:" << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; *q += 13; // change value of the object q owns p = q; cout << "after change and reassignment:" << endl; cout << " p: " << p << endl; cout << " q: " << q << endl; }
相关文章推荐
- 《The C++ Standard Library》第50页 关于传递auto_ptr的问题
- The C++ Standard Library : A Tutoral and Reference 读书笔记之auto_ptr
- 《The C++ Standard Library》第45页 用const修饰auto_ptr的注意事项
- The C++ Standard Library: shared_ptr and unique_ptr
- c++ standard library 学习笔记-auto_ptr<T> 注意事项
- 《The C++ Standard Library》第41页 不要误解了这段话
- The C++ Standard Library Extensions: A Tutorial and Reference
- [unresolved]《The C++ Standard Library》第50页 该如何理解exception to the rule
- error This file requires compiler and library support for the ISO C++ 2011 standard
- 错误:fatal error C1189: #error : The C++ Standard Library forbids macroizing keywords. Enable warning
- The C++ Standard Library Extensions: A Tutorial and Reference
- use the Standard C++ Library in symbian
- Question 6: Which of the following are container adapters in the STL (Standard Template Library) in C++?
- Power up C++ with the Standard Template Library: Part I[翻译]
- Beyond the C++ Standard Library: An Introduction to Boost by Bjцrn Karlsson
- 个人翻译Beyond the C++ Standard Library
- 错误:fatal error C1189: #error : The C++ Standard Library forbids macroizing keywords. Enable warning
- C++中使用array报错 requires compiler and library surpport for the ISO c++ 2011 standard
- The C++ Standard Library: Standard Exception Classes
- VS2013解决 The C++ Standard Library forbids macroizing keywords.