亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
久久色.com| 欧美成人三级在线| 成人免费va视频| 国产一区二区三区四区五区美女| 日韩精品免费专区| 日韩二区在线观看| 久久精品噜噜噜成人av农村| 免费在线看成人av| 久久99精品国产麻豆不卡| 免费成人在线影院| 国产乱码精品1区2区3区| 国产精品99久久久久久久女警 | 国产精品入口麻豆原神| 国产丝袜在线精品| 亚洲欧洲国产日韩| 亚洲黄色免费电影| 日韩和欧美一区二区| 欧美bbbbb| 国产精品一区二区久久精品爱涩| 国产美女一区二区三区| 不卡的电视剧免费网站有什么| 91小视频免费观看| 欧美日韩1区2区| 久久伊99综合婷婷久久伊| 国产精品麻豆久久久| 亚洲午夜久久久久久久久电影网| 天天色天天操综合| 国产精品自产自拍| 色综合视频在线观看| 欧美日韩视频专区在线播放| 精品欧美久久久| 国产精品理论片| 视频一区欧美日韩| 国产成a人亚洲精品| 欧美私人免费视频| 久久精品一区八戒影视| 亚洲自拍与偷拍| 国产精品一二二区| 欧美日韩免费视频| 国产日韩精品一区二区三区| 亚洲香肠在线观看| 国产ts人妖一区二区| 欧美日韩精品一区二区三区蜜桃| 久久女同性恋中文字幕| 一区二区三区波多野结衣在线观看| 日韩**一区毛片| 91免费国产在线观看| 337p粉嫩大胆色噜噜噜噜亚洲| 亚洲人精品午夜| 激情综合网激情| 欧美性受xxxx| 中文字幕欧美一| 国产精品综合网| 欧美日韩色综合| 亚洲欧美一区二区视频| 经典三级在线一区| 欧美男人的天堂一二区| 中文字幕字幕中文在线中不卡视频| 人妖欧美一区二区| 欧美日韩中字一区| 亚洲乱码中文字幕| 岛国精品一区二区| 日韩欧美国产综合| 午夜精品久久久久| 欧美性大战久久| 亚洲视频网在线直播| 成人av午夜影院| 久久蜜桃香蕉精品一区二区三区| 蜜桃精品视频在线| 91精品国产一区二区人妖| 亚洲成a人v欧美综合天堂| 日本乱人伦aⅴ精品| 中文字幕日韩一区二区| 不卡的看片网站| 久久久www成人免费毛片麻豆| 免费久久精品视频| 日韩一区二区三免费高清| 午夜久久久久久久久| 欧美日韩精品欧美日韩精品一| 一区二区不卡在线播放| 欧美三级一区二区| 午夜免费久久看| 欧美一区二区大片| 久久精品99国产国产精| 日韩欧美一区二区久久婷婷| 视频一区二区三区在线| 欧美一区二区三区免费| 久久精品72免费观看| 久久久久国产免费免费| 国产成人av一区二区| 国产精品久久久久久妇女6080| voyeur盗摄精品| 亚洲一区中文日韩| 欧美日韩五月天| 免费观看一级特黄欧美大片| 日韩欧美国产综合一区| 国产精品白丝jk黑袜喷水| 国产精品乱码妇女bbbb| 色国产综合视频| 午夜影视日本亚洲欧洲精品| 欧美电影在哪看比较好| 蜜桃免费网站一区二区三区| 欧美国产禁国产网站cc| 91色porny在线视频| 首页国产欧美久久| 国产午夜精品在线观看| 色偷偷久久人人79超碰人人澡| 日韩二区三区在线观看| 国产人成一区二区三区影院| 色婷婷av一区二区三区gif| 日韩精品电影一区亚洲| 国产女人aaa级久久久级| 在线观看亚洲精品视频| 国产在线视视频有精品| 亚洲蜜臀av乱码久久精品| 日韩一区二区三区三四区视频在线观看| 国产suv一区二区三区88区| 五月激情六月综合| 亚洲国产高清不卡| 91精品国产乱| 99精品久久免费看蜜臀剧情介绍| 日韩电影在线一区| 一区二区三区欧美日| 久久一夜天堂av一区二区三区| 欧美亚洲动漫精品| 丰满亚洲少妇av| 久热成人在线视频| 亚洲国产日韩a在线播放| 国产欧美日韩激情| 欧美一卡二卡三卡| 日本高清视频一区二区| 丁香激情综合国产| 九九九久久久精品| 性做久久久久久| 成人免费在线观看入口| 精品国产91亚洲一区二区三区婷婷| 在线视频一区二区免费| 国产a区久久久| 九一九一国产精品| 日韩av一区二区在线影视| 亚洲免费在线视频一区 二区| 久久精品欧美一区二区三区麻豆| 欧美一级午夜免费电影| 538prom精品视频线放| 欧美在线观看禁18| 色94色欧美sute亚洲线路一久 | 国产亲近乱来精品视频 | 久久se这里有精品| 日韩影院精彩在线| 亚洲一二三四区不卡| 日韩美女视频一区| 日韩一区日韩二区| 国产精品色哟哟网站| 中文字幕精品在线不卡| 欧美精彩视频一区二区三区| 久久久久国产精品厨房| 久久久久久电影| 久久久久97国产精华液好用吗| 日韩精品一区国产麻豆| 日韩欧美激情一区| 久久亚洲综合色一区二区三区| 26uuu国产在线精品一区二区| 欧美成人午夜电影| 久久久亚洲精品一区二区三区| 欧美大黄免费观看| 久久久久国产精品厨房| 国产精品美女视频| 亚洲男人的天堂一区二区| 亚洲地区一二三色| 免费观看久久久4p| 国产精品一区二区三区99| 成人黄色av电影| 欧美午夜在线观看| 欧美一区二区三区四区高清| 精品区一区二区| 国产精品久久久久久久第一福利 | 一区二区三区中文字幕| 亚洲妇熟xx妇色黄| 理论电影国产精品| 成人av电影免费在线播放| 91久久香蕉国产日韩欧美9色| 7777精品伊人久久久大香线蕉经典版下载 | 欧美日韩国产大片| 日韩久久久精品| 国产精品麻豆99久久久久久| 亚洲国产日韩a在线播放| 久久国产尿小便嘘嘘尿| 国产不卡视频一区二区三区| 欧美专区在线观看一区| 精品久久一区二区三区| 中文字幕一区二区三区色视频| 午夜日韩在线电影| 成人av在线网| 欧美va在线播放| 亚洲综合在线五月| 国产精品18久久久久久久久久久久 | 日韩三区在线观看| 国产精品久线在线观看| 日韩成人伦理电影在线观看| 成人午夜私人影院|