亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? sutter.htm

?? 教你如何編寫有效簡潔的出C++程序
?? HTM
?? 第 1 頁 / 共 4 頁
字號:
 Exception-Safe Generic Containers. By Herb Sutter This is an updated version of an article that appeared in the September and November-December 1997 issues of the C++ Report.Exception-Safe Generic Containersby Herb SutterException handling and generic programming are two of C++'s most powerful features. Both, however, require exceptional care, and writing an efficient reusable generic container is nearly as difficult as writing exception-safe code.This article tackles both of these major features at once, by examining how to write exception-safe (works properly in the presence of exceptions) and exception-neutral (propagates all exceptions to the caller) generic containers. That's easy enough to say, but it's no mean feat. If you have any doubts on that score, see Tom Cargill's excellent article, Exception Handling: A False Sense of Security.This article begins where Cargill's left off, namely by presenting an exception-neutral version of the Stack template he critiques. In the end, we'll significantly improve the Stack container by reducing the requirements on T, the contained type, and show advanced techniques for managing resources exception-safely. Along the way we'll find the answers to questions like the following: What are the different "levels" of exception safety? Can or should generic containers be fully exception-neutral? Are the standard library containers exception-safe or -neutral? Does exception safety affect the design of your container's public interface? Should generic containers use exception specifications?The Stack ContainerHere is the declaration of the Stack template, substantially the same as in Cargill's article. Our mission: to make Stack exception-neutral. That is, Stack objects should always be in a correct and consistent state regardless of any exceptions that might be thrown in the course of executing Stack's member functions, and if any exceptions are thrown they should be propagated seamlessly through to the caller, who can deal with them as he pleases because he knows the context of T and we don't. template <class T> class Stack {public:  Stack();  ~Stack();  Stack(const Stack  Stackoperator=(const Stack  size_t Size() const;  void   Push(const T  T      Pop();               // if empty, throws exceptionprivate:  T*     v_;                  // ptr to a memory area big  size_t vsize_;              //  enough for 'vsize_' T's  size_t vused_;              // # of T's actually in use};Before reading on, stop and think about this container and consider: What are the exception-safety issues? How can this class be made exception-neutral, so that any exceptions are propagated to the caller without causing integrity problems in a Stack object?Default ConstructionRight away, we can see that Stack is going to have to manage dynamic memory resources. Clearly one key is going to be avoiding leaks even in the presence of exceptions thrown by T operations and standard memory allocations. For now, we'll manage these memory resources within each Stack member function. Later, we'll improve on this by using a private base class (see Item E42) to encapsulate resource ownership.First, consider one possible default constructor: template<class T>Stack<T>::Stack()  : v_(0),  vsize_(10),  vused_(0)           // nothing used yet{  v_ = new T[vsize_]; // initial allocation}Is this constructor exception-safe? To find out, consider what might throw. In short, the answer is: "Any function." So the first step is to analyze this code and determine what functions will actually be called, including both free functions and constructors, destructors, operators, and other member functions.This Stack constructor first sets vsize_ to 10, then attempts to allocate some initial memory using new T[vsize_]. The latter first tries to call operator new[] (either the default operator new[] or one provided by T see Item M8) to allocate the memory, then tries to call T::T a total of vsize_ times. There are two operations that might fail: first, the memory allocation itself, in which case operator new[] will throw a bad_alloc exception; and second, T's default constructor, which might throw anything at all, and in which case any objects that were constructed are destroyed and the allocated memory is automatically guaranteed to be deallocated via operator delete[]. (See Item M8 and the sidebar to Scott Meyers' article, Counting Objects in C++.)Hence the above function is fully exception-safe, and we can move on to the next ...... what? Why is it exception-safe, you ask? All right, let's examine it in a little more detail: We're exception-neutral. We don't catch anything, so if the new throws then the exception is correctly propagated up to our caller as required. We don't leak. If the operator new[] allocation call exited by throwing a bad_alloc exception, then no memory was allocated to begin with so there can't be a leak. If one of the T constructors threw, then any T objects that were fully constructed were properly destroyed and finally operator delete[] was automatically called to release the memory. That makes us leak-proof, as advertised. (I'm ignoring for now the possibility that one of the T destructor calls might throw during the cleanup, which would call terminate() and simply kill the program altogether and leave events well out of your control anyway. See below for more information on Destructors That Throw and Why They're Evil.) We're in a consistent state whether any part of the new throws or not. Now, you might think that if the new throws, then vsize_ has already been set to 10 when in fact nothing was successfully allocated. Isn't that inconsistent? Not really, because it's irrelevant. Remember, if the new throws we propagate the exception out of our own constructor, right? And, by definition, "exiting a constructor by means of an exception" means our Stack proto-object never actually got to become a completely constructed object at all, its lifetime never started, and hence its state is meaningless because the object never existed. It doesn't matter what the memory that briefly held vsize_ was set to, any more than it matters what the memory was set to after we leave an object's destructor. All that's left is raw memory, smoke and ashes.All right, I'll admit it... I put the new in the constructor body purely to open the door for that last #3 discussion. What I'd actually prefer to write is: template<class T>Stack<T>::Stack()  : v_(new T[10]),  // default allocation    vsize_(10),    vused_(0)       // nothing used yet{ }Both versions are practically equivalent. I prefer the latter because it follows the usual good practice of initializing members in initializer lists whenever possible (see Item E12).DestructionThe destructor looks a lot easier, once we make a (greatly) simplifying assumption: template<class T>Stack<T>::~Stack() {  delete[] v_;      // this can't throw  }Why can't the delete[] call throw? Recall that this invokes T::~T for each object in the array, then calls operator delete[] to deallocate the memory (see Item M8). Now, we know that the deallocation by operator delete[] may never throw, because its signature is always one of the following: void operator delete[]( void* ) throw();void operator delete[]( void*, size_t ) throw();Strictly speaking, this doesn't prevent someone from providing an overloaded operator delete[] that does throw, but any such overload would violate this clear intent and should be considered defective. Hence the only thing that could possibly throw is one of the T::~T calls, and we're arbitrarily going to have Stack require that T::~T may not throw. Why? To make a long story short, we just can't implement the Stack destructor with complete exception safety if T::~T can throw, that's why. However, requiring that T::~T may not throw isn't particularly onerous, because there are plenty of other reasons why destructors should never be allowed to throw at all. (Frankly, you won't go far wrong if you just habitually write throw() after the declaration of every destructor you ever write. Even if exception specifications cause expensive checks under your current compiler (see Item M15), at least write all your destructors as though they were specified as throw()... that is, never allow exceptions to leave destructors.) Any class whose destructor can throw is likely to cause you all sorts of other problems anyway sooner or later, and you can't even reliably new[] or delete[] an array of them. More on that later.Copy Construction and Copy AssignmentThe next few functions will use a common helper function, NewCopy, to manage allocating and growing memory. NewCopy takes a pointer to (src) and size of (srcsize) an existing T buffer, and returns a pointer to a new and possibly larger copy of the buffer, passing ownership of the new buffer to the caller. If exceptions are encountered, NewCopy correctly releases all temporary resources and propagates the exception in such a way that nothing is leaked. template<class T>T* NewCopy( const T* src,    size_t   srcsize,    size_t   destsize ) {  assert( destsize = srcsize );  T* dest = new T[destsize];  try {    copy( src, src+srcsize, dest );    // copy is part of the STL;                                       // see Item M35  } catch(...) {    delete[] dest;                    // this can't throw    throw;                             // rethrow original exception  }  return dest;}Let's analyze this one step at a time: In the new statement, the allocation might throw bad_alloc or the T::T's may throw anything. In either case, nothing is allocated and we simply allow the exception to propagate. This is leak-free and exception-neutral. Next, we assign all the existing values using copy, and copy invokes T::operator=. If any of the assignments fail, we catch the exception, free the allocated memory, and rethrow the original exception. This is again both leak-free and exception-neutral. However, there's an important subtlety here: T::operator= must guarantee that, if it does throw, then the assigned-to T object must be unchanged. (Later, I will show an improved version of Stack which does not rely on T::operator=.) If the allocation and copy both succeeded, then we return the pointer to the new buffer and relinquish ownership (that is, the caller is responsible for the buffer from here on out). The return simply copies the pointer value, which cannot throw.With NewCopy in hand, the Stack copy constructor is easy to write: template<class T>Stack<T>::Stack( const Stack<T>other )  : v_(NewCopy( other.v_,      other.vsize_,      other.vsize_ )),    vsize_(other.vsize_),    vused_(other.vused_){ }The only possible exception is from NewCopy, which manages its own resources. Next, we tackle copy assignment: template<class T>Stack<T>Stack<T>::operator=( const Stack<T>other ) {  if( this != ) {    T* v_new = NewCopy( other.v_,      other.vsize_,	  other.vsize_ );    delete[] v_;  // this can't throw    v_ = v_new;    // take ownership    vsize_ = other.vsize_;    vused_ = other.vused_;  }  return *this;    // safe, no copy involved}Again, after the routine weak guard against self-assignment (see Item E17), only the NewCopy call might throw; if it does, we correctly propagate that exception without affecting the Stack object's state. To the caller, if the assignment throws then the state is unchanged, and if the assignment doesn't throw then the assignment and all of its side effects are successful and complete.Size(), Push(), and Pop()The easiest of all Stack's members to implement safely is Size, because all it does is copy a built-in which can never throw: template<class T>size_t Stack<T>::Size() const {  return vused_;  // safe, builtins don't throw}However, with Push we need to apply our now-usual duty of care: template<class T>void Stack<T>::Push( const Tt ) {  if( vused_ == vsize_ )             // grow if necessary  {                                  // by some grow factor    size_t vsize_new = vsize_*2+1;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产在线精品一区二区三区不卡| 一区二区三区成人| 91麻豆精品国产无毒不卡在线观看| www..com久久爱| 国产乱子伦视频一区二区三区 | 亚洲最新视频在线观看| 中文字幕乱码久久午夜不卡| 久久久久国产精品人| 中文字幕av一区 二区| 国产精品美女久久久久av爽李琼| 国产精品久久久久久久第一福利 | 欧美在线制服丝袜| 91国产成人在线| 欧美主播一区二区三区| 欧美日韩高清一区二区三区| 91麻豆精品国产自产在线观看一区 | 日韩欧美激情一区| 国产偷国产偷精品高清尤物| 国产欧美日韩在线看| 日本一二三四高清不卡| 亚洲乱码中文字幕综合| 亚洲成人免费视| 精品一区二区成人精品| 国产成人在线网站| 91黄视频在线观看| 欧美一区永久视频免费观看| 久久噜噜亚洲综合| 亚洲美女少妇撒尿| 日本女优在线视频一区二区| 国产老女人精品毛片久久| 成人国产一区二区三区精品| 欧美午夜精品电影| 精品国产欧美一区二区| 国产精品久久久久久亚洲伦 | 精品入口麻豆88视频| 日本一区二区视频在线观看| 一区二区三区四区国产精品| 久久99九九99精品| 成人理论电影网| 日韩一区二区三区四区| 亚洲丝袜另类动漫二区| 九九热在线视频观看这里只有精品| 福利电影一区二区| 欧美日韩免费视频| 亚洲国产精华液网站w| 天天av天天翘天天综合网色鬼国产| 韩国三级电影一区二区| 欧美午夜寂寞影院| 国产精品久久久久四虎| 久久国产免费看| 欧美视频在线一区二区三区| 久久久久88色偷偷免费| 日韩国产欧美一区二区三区| 不卡一区二区在线| 精品国产精品网麻豆系列| 午夜欧美视频在线观看| 99久久精品免费| 国产午夜精品久久久久久久| 日韩极品在线观看| 欧美在线免费观看亚洲| 国产精品久久久久久久久免费桃花 | 日本v片在线高清不卡在线观看| 99精品国产99久久久久久白柏| 久久综合成人精品亚洲另类欧美 | 91麻豆自制传媒国产之光| 日韩免费观看高清完整版 | 久久久精品日韩欧美| 偷拍自拍另类欧美| 欧美午夜一区二区三区| 国产精品卡一卡二| 北条麻妃一区二区三区| 国产欧美视频一区二区| 国产一区二区精品久久| 精品国产sm最大网站免费看| 麻豆精品视频在线观看视频| 欧美一区二区三区视频在线观看 | 国产不卡视频在线播放| 久久久亚洲高清| 国产精品18久久久久久久久| 久久亚洲综合av| 国产一区二区三区免费播放| 久久午夜色播影院免费高清| 国内精品伊人久久久久影院对白| 精品久久99ma| 国产91精品在线观看| 中文字幕av资源一区| 91亚洲精品乱码久久久久久蜜桃| 国产精品成人网| 欧美视频第二页| 久久福利资源站| 国产欧美一区二区精品久导航| 成人免费毛片app| 亚洲男人天堂av| 欧美高清一级片在线| 精品一区二区三区在线观看 | 91国产免费观看| 日精品一区二区| 久久久亚洲综合| 97精品久久久午夜一区二区三区| 一区二区三区成人在线视频| 欧美日韩中文字幕一区| 久久99精品久久久久| 国产日韩v精品一区二区| 色综合色狠狠天天综合色| 同产精品九九九| 国产人久久人人人人爽| 91美女视频网站| 蜜桃免费网站一区二区三区 | 91色视频在线| 日本vs亚洲vs韩国一区三区| 欧美国产视频在线| 欧美艳星brazzers| 国产激情视频一区二区在线观看| 亚洲人一二三区| 精品国产123| 欧美色综合影院| 丁香六月久久综合狠狠色| 亚洲va欧美va天堂v国产综合| 日韩欧美国产午夜精品| 91黄色免费观看| 国产精品99久久久久久久vr| 亚洲国产中文字幕| 国产精品国产成人国产三级| 欧美一级理论片| 色婷婷av一区二区三区gif| 激情六月婷婷久久| 日韩电影在线观看电影| 中文字幕日韩av资源站| www亚洲一区| 911精品国产一区二区在线| 91无套直看片红桃| 国产成人在线看| 日本不卡视频在线| 亚欧色一区w666天堂| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆| 欧美高清你懂得| 色诱视频网站一区| 99精品在线观看视频| 国产专区欧美精品| 久久精品国产在热久久| 污片在线观看一区二区| 亚洲一区二区高清| 亚洲色图.com| 亚洲欧洲无码一区二区三区| 久久亚洲综合av| 久久久精品天堂| 国产日产欧美一区| 国产欧美精品在线观看| 久久久精品国产免费观看同学| 制服.丝袜.亚洲.中文.综合| 欧美日韩国产首页| 9191久久久久久久久久久| 欧美性猛交xxxx黑人交| 欧美在线一二三| 欧美日韩黄色影视| 欧美精品免费视频| 在线综合视频播放| 精品国产污污免费网站入口| 欧美成人精品二区三区99精品| 日韩欧美国产一区在线观看| 精品少妇一区二区三区视频免付费| 欧美一区二区视频在线观看| 日韩欧美的一区二区| 久久综合五月天婷婷伊人| 精品国产凹凸成av人导航| 国产欧美综合色| 欧美国产综合色视频| 综合久久综合久久| 亚洲高清不卡在线观看| 老司机免费视频一区二区三区| 精品一区二区三区在线视频| 高清在线观看日韩| 91丨porny丨国产| 欧美裸体一区二区三区| 日韩欧美一区在线| 欧美激情一区二区三区全黄| 亚洲欧美电影一区二区| 五月天久久比比资源色| 国产精品自在在线| 91麻豆自制传媒国产之光| 欧美年轻男男videosbes| 日韩精品在线网站| 中文字幕一区二区5566日韩| 婷婷开心激情综合| 国产精品一卡二卡| 色www精品视频在线观看| 日韩你懂的在线播放| 国产女同性恋一区二区| 亚洲丶国产丶欧美一区二区三区| 奇米四色…亚洲| 99久久er热在这里只有精品15| 9191久久久久久久久久久| 国产精品乱码一区二三区小蝌蚪| 亚洲成人高清在线| 国产成人综合亚洲网站| 777精品伊人久久久久大香线蕉| 国产午夜久久久久| 日韩 欧美一区二区三区| 91猫先生在线| 欧美国产欧美综合|