久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

  • <legend id='pkKRV'><style id='pkKRV'><dir id='pkKRV'><q id='pkKRV'></q></dir></style></legend>
      1. <tfoot id='pkKRV'></tfoot>

      2. <i id='pkKRV'><tr id='pkKRV'><dt id='pkKRV'><q id='pkKRV'><span id='pkKRV'><b id='pkKRV'><form id='pkKRV'><ins id='pkKRV'></ins><ul id='pkKRV'></ul><sub id='pkKRV'></sub></form><legend id='pkKRV'></legend><bdo id='pkKRV'><pre id='pkKRV'><center id='pkKRV'></center></pre></bdo></b><th id='pkKRV'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='pkKRV'><tfoot id='pkKRV'></tfoot><dl id='pkKRV'><fieldset id='pkKRV'></fieldset></dl></div>

        <small id='pkKRV'></small><noframes id='pkKRV'>

        • <bdo id='pkKRV'></bdo><ul id='pkKRV'></ul>

        C++中的對(duì)象銷毀

        Object destruction in C++(C++中的對(duì)象銷毀)
          <bdo id='5cRkc'></bdo><ul id='5cRkc'></ul>
            <tbody id='5cRkc'></tbody>
          <tfoot id='5cRkc'></tfoot>
            <i id='5cRkc'><tr id='5cRkc'><dt id='5cRkc'><q id='5cRkc'><span id='5cRkc'><b id='5cRkc'><form id='5cRkc'><ins id='5cRkc'></ins><ul id='5cRkc'></ul><sub id='5cRkc'></sub></form><legend id='5cRkc'></legend><bdo id='5cRkc'><pre id='5cRkc'><center id='5cRkc'></center></pre></bdo></b><th id='5cRkc'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='5cRkc'><tfoot id='5cRkc'></tfoot><dl id='5cRkc'><fieldset id='5cRkc'></fieldset></dl></div>
            <legend id='5cRkc'><style id='5cRkc'><dir id='5cRkc'><q id='5cRkc'></q></dir></style></legend>

            1. <small id='5cRkc'></small><noframes id='5cRkc'>

                  本文介紹了C++中的對(duì)象銷毀的處理方法,對(duì)大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

                  問題描述

                  C++ 中的對(duì)象究竟何時(shí)被銷毀,這意味著什么?由于沒有垃圾收集器,我是否必須手動(dòng)銷毀它們?異常如何發(fā)揮作用?

                  (注意:這是Stack Overflow 的 C++ 常見問題解答的條目.如果您想批評(píng)以這種形式提供常見問題解答,然后 開始在元數(shù)據(jù)上發(fā)帖所有這些都可以做到這一點(diǎn).C++ 聊天室中監(jiān)控該問題的答案a>,F(xiàn)AQ 的想法最初是從這里開始的,因此您的答案很可能會(huì)被提出該想法的人閱讀.)

                  解決方案

                  在下面的文本中,我將區(qū)分作用域?qū)ο?/em>,它們的銷毀時(shí)間由它們的封閉作用域(函數(shù)、塊、類、表達(dá)式)和動(dòng)態(tài)對(duì)象,它們的確切銷毀時(shí)間通常要到運(yùn)行時(shí)才能知道.

                  雖然類對(duì)象的銷毀語義由析構(gòu)函數(shù)決定,但標(biāo)量對(duì)象的銷毀始終是空操作.具體來說,銷毀指針變量不會(huì)銷毀指針對(duì)象.

                  作用域?qū)ο?/h1>

                  自動(dòng)對(duì)象

                  當(dāng)控制流離開其定義的范圍時(shí),自動(dòng)對(duì)象(通常稱為局部變量")將按照其定義的相反順序進(jìn)行銷毀:

                  void some_function(){福一;福 b;如果(some_condition){傅y;福茲;} <--- z 和 y 在這里被破壞} <--- b 和 a 在這里被破壞

                  如果在函數(shù)執(zhí)行過程中拋出異常,則在異常傳播到調(diào)用者之前,所有先前構(gòu)造的自動(dòng)對(duì)象都會(huì)被銷毀.這個(gè)過程稱為堆棧展開.在堆棧展開期間,前面提到的自動(dòng)對(duì)象的析構(gòu)函數(shù)不會(huì)再有任何異常.否則,函數(shù) std::terminate 被調(diào)用.

                  這引出了 C++ 中最重要的準(zhǔn)則之一:

                  <塊引用>

                  析構(gòu)函數(shù)不應(yīng)該拋出.

                  非本地靜態(tài)對(duì)象

                  在命名空間范圍內(nèi)定義的靜態(tài)對(duì)象(通常稱為全局變量")和靜態(tài)數(shù)據(jù)成員在執(zhí)行main后按照其定義的相反順序被銷毀:

                  struct X{靜態(tài) Foo x;//這只是一個(gè)*聲明*,而不是*定義*};福一;福 b;int main(){} <--- y, x, b 和 a 在這里被破壞福 X::x;//這是各自的定義傅y;

                  請(qǐng)注意,在不同翻譯單元中定義的靜態(tài)對(duì)象的構(gòu)造(和銷毀)的相對(duì)順序是未定義的.

                  如果異常離開靜態(tài)對(duì)象的析構(gòu)函數(shù),則調(diào)用函數(shù)std::terminate.

                  本地靜態(tài)對(duì)象

                  在函數(shù)內(nèi)部定義的靜態(tài)對(duì)象是在(如果)控制流第一次通過它們的定義時(shí)構(gòu)造的.1main 執(zhí)行后,它們以相反的順序銷毀:

                  Foo&get_some_Foo(){靜態(tài) Foo x;返回 x;}酒吧&get_some_Bar(){靜態(tài)酒吧 y;返回 y;}int main(){get_some_Bar().do_something();//注意 get_some_Bar 被稱為 *first*get_some_Foo().do_something();} <--- x 和 y 在這里被破壞//因此 y 被破壞 *last*

                  如果異常離開靜態(tài)對(duì)象的析構(gòu)函數(shù),則調(diào)用函數(shù)std::terminate.

                  1:這是一個(gè)極其簡化的模型.靜態(tài)對(duì)象的初始化細(xì)節(jié)其實(shí)要復(fù)雜得多.

                  基類子對(duì)象和成員子對(duì)象

                  當(dāng)控制流離開對(duì)象的析構(gòu)函數(shù)體時(shí),其成員子對(duì)象(也稱為其數(shù)據(jù)成員")按照其定義的相反順序進(jìn)行析構(gòu).之后,它的基類子對(duì)象按照基類說明符列表的相反順序銷毀:

                  class Foo : Bar, Baz{庫克斯 x;曲y;上市:~Foo(){} <--- y 和 x 在這里被破壞,};其次是 Baz 和 Bar 基類子對(duì)象

                  如果在 Foo 的子對(duì)象之一的構(gòu)造過程中拋出異常,那么在傳播異常之前,其先前構(gòu)造的所有子對(duì)象都將被銷毀.另一方面,Foo 析構(gòu)函數(shù)將不會(huì)被執(zhí)行,因?yàn)?Foo 對(duì)象從未被完全構(gòu)造過.

                  請(qǐng)注意,析構(gòu)函數(shù)體不負(fù)責(zé)析構(gòu)數(shù)據(jù)成員本身.如果數(shù)據(jù)成員是對(duì)象銷毀時(shí)需要釋放的資源的句柄(例如文件、套接字、數(shù)據(jù)庫連接、互斥鎖或堆內(nèi)存),則只需編寫析構(gòu)函數(shù).

                  數(shù)組元素

                  數(shù)組元素按降序銷毀.如果在第 n 個(gè)元素的構(gòu)造過程中拋出異常,則在傳播異常之前先銷毀第 n-1 到 0 個(gè)元素.

                  臨時(shí)對(duì)象

                  當(dāng)評(píng)估類類型的純右值表達(dá)式時(shí),會(huì)構(gòu)造一個(gè)臨時(shí)對(duì)象.prvalue 表達(dá)式最突出的例子是調(diào)用按值返回對(duì)象的函數(shù),例如 T operator+(const T&, const T&).一般情況下,當(dāng)詞法上包含純右值的完整表達(dá)式被完全求值時(shí),臨時(shí)對(duì)象就會(huì)被破壞:

                  __________________________ 完整表達(dá)式___________子表達(dá)式_______ 子表達(dá)式some_function(a + " " + b);^ 兩個(gè)臨時(shí)對(duì)象都在這里被破壞

                  上面的函數(shù)調(diào)用 some_function(a + " " + b) 是一個(gè)完整的表達(dá)式,因?yàn)樗皇歉蟊磉_(dá)式的一部分(相反,它是表達(dá)式語句的一部分).因此,在評(píng)估子表達(dá)式期間構(gòu)造的所有臨時(shí)對(duì)象都將在分號(hào)處銷毀.有兩個(gè)這樣的臨時(shí)對(duì)象:第一個(gè)是在第一次加法時(shí)構(gòu)造的,第二個(gè)是在第二次加法時(shí)構(gòu)造的.第二個(gè)臨時(shí)對(duì)象將在第一個(gè)之前銷毀.

                  如果在第二次添加過程中拋出異常,第一個(gè)臨時(shí)對(duì)象將在傳播異常之前正確銷毀.

                  如果局部引用是用純右值表達(dá)式初始化的,臨時(shí)對(duì)象的生命周期會(huì)擴(kuò)展到局部引用的范圍,所以你不會(huì)得到一個(gè)懸空引用:

                  <代碼>{const Foo&r = a + " " + b;^ 第一個(gè)臨時(shí) (a + " ") 在這里被破壞//...} <--- 第二個(gè)臨時(shí) (a + " " + b) 直到這里才被破壞

                  如果計(jì)算非類類型的純右值表達(dá)式,結(jié)果是一個(gè),而不是一個(gè)臨時(shí)對(duì)象.但是,如果使用純右值來初始化引用,則構(gòu)造一個(gè)臨時(shí)對(duì)象:

                  const int&r = i + j;

                  動(dòng)態(tài)對(duì)象和數(shù)組

                  在下一節(jié)中,destroy X 的意思是先銷毀 X,然后釋放底層內(nèi)存".類似地,create X 的意思是先分配足夠的內(nèi)存,然后在那里構(gòu)造 X".

                  動(dòng)態(tài)對(duì)象

                  通過p = new Foo 創(chuàng)建的動(dòng)態(tài)對(duì)象通過delete p 銷毀.如果你忘記delete p,你就有了資源泄漏.您永遠(yuǎn)不應(yīng)嘗試執(zhí)行以下操作之一,因?yàn)樗鼈兌紩?huì)導(dǎo)致未定義的行為:

                  • 通過delete[](注意方括號(hào))、free 或任何其他方式銷毀動(dòng)態(tài)對(duì)象
                  • 多次銷毀動(dòng)態(tài)對(duì)象
                  • 在動(dòng)態(tài)對(duì)象被銷毀后訪問它

                  如果在動(dòng)態(tài)對(duì)象的構(gòu)造過程中拋出異常,則在傳播異常之前釋放底層內(nèi)存.(析構(gòu)函數(shù)將不會(huì)在內(nèi)存釋放之前執(zhí)行,因?yàn)閷?duì)象從未完全構(gòu)造過.)

                  動(dòng)態(tài)數(shù)組

                  通過p = new Foo[n] 創(chuàng)建的動(dòng)態(tài)數(shù)組通過delete[] p 銷毀(注意方括號(hào)).如果你忘記delete[] p,你就有了資源泄漏.您永遠(yuǎn)不應(yīng)嘗試執(zhí)行以下操作之一,因?yàn)樗鼈兌紩?huì)導(dǎo)致未定義的行為:

                  • 通過deletefree或任何其他方式銷毀動(dòng)態(tài)數(shù)組
                  • 多次銷毀動(dòng)態(tài)數(shù)組
                  • 在動(dòng)態(tài)數(shù)組被銷毀后訪問它

                  如果在第n個(gè)元素的構(gòu)造過程中拋出異常,則按降序銷毀n-1到0個(gè)元素,釋放底層內(nèi)存,并傳播異常.

                  (對(duì)于動(dòng)態(tài)數(shù)組,您通常應(yīng)該更喜歡 std::vector 而不是 Foo*.它使編寫正確和健壯的代碼變得更加容易.)

                  引用計(jì)數(shù)智能指針

                  一個(gè)由多個(gè)std::shared_ptr對(duì)象管理的動(dòng)態(tài)對(duì)象在最后一個(gè)參與共享的std::shared_ptr對(duì)象銷毀過程中被銷毀那個(gè)動(dòng)態(tài)對(duì)象.

                  (對(duì)于共享對(duì)象,您通常應(yīng)該更喜歡 std::shared_ptr<Foo> 而不是 Foo*.它使編寫正確和健壯的代碼變得更加容易.)

                  When exactly are objects destroyed in C++, and what does that mean? Do I have to destroy them manually, since there is no Garbage Collector? How do exceptions come into play?

                  (Note: This is meant to be an entry to Stack Overflow's C++ FAQ. If you want to critique the idea of providing an FAQ in this form, then the posting on meta that started all this would be the place to do that. Answers to that question are monitored in the C++ chatroom, where the FAQ idea started out in the first place, so your answer is very likely to get read by those who came up with the idea.)

                  解決方案

                  In the following text, I will distinguish between scoped objects, whose time of destruction is statically determined by their enclosing scope (functions, blocks, classes, expressions), and dynamic objects, whose exact time of destruction is generally not known until runtime.

                  While the destruction semantics of class objects are determined by destructors, the destruction of a scalar object is always a no-op. Specifically, destructing a pointer variable does not destroy the pointee.

                  Scoped objects

                  automatic objects

                  Automatic objects (commonly referred to as "local variables") are destructed, in reverse order of their definition, when control flow leaves the scope of their definition:

                  void some_function()
                  {
                      Foo a;
                      Foo b;
                      if (some_condition)
                      {
                          Foo y;
                          Foo z;
                      }  <--- z and y are destructed here
                  }  <--- b and a are destructed here
                  

                  If an exception is thrown during the execution of a function, all previously constructed automatic objects are destructed before the exception is propagated to the caller. This process is called stack unwinding. During stack unwinding, no further exceptions may leave the destructors of the aforementioned previously constructed automatic objects. Otherwise, the function std::terminate is called.

                  This leads to one of the most important guidelines in C++:

                  Destructors should never throw.

                  non-local static objects

                  Static objects defined at namespace scope (commonly referred to as "global variables") and static data members are destructed, in reverse order of their definition, after the execution of main:

                  struct X
                  {
                      static Foo x;   // this is only a *declaration*, not a *definition*
                  };
                  
                  Foo a;
                  Foo b;
                  
                  int main()
                  {
                  }  <--- y, x, b and a are destructed here
                  
                  Foo X::x;           // this is the respective definition
                  Foo y;
                  

                  Note that the relative order of construction (and destruction) of static objects defined in different translation units is undefined.

                  If an exception leaves the destructor of a static object, the function std::terminate is called.

                  local static objects

                  Static objects defined inside functions are constructed when (and if) control flow passes through their definition for the first time.1 They are destructed in reverse order after the execution of main:

                  Foo& get_some_Foo()
                  {
                      static Foo x;
                      return x;
                  }
                  
                  Bar& get_some_Bar()
                  {
                      static Bar y;
                      return y;
                  }
                  
                  int main()
                  {
                      get_some_Bar().do_something();    // note that get_some_Bar is called *first*
                      get_some_Foo().do_something();
                  }  <--- x and y are destructed here   // hence y is destructed *last*
                  

                  If an exception leaves the destructor of a static object, the function std::terminate is called.

                  1: This is an extremely simplified model. The initialization details of static objects are actually much more complicated.

                  base class subobjects and member subobjects

                  When control flow leaves the destructor body of an object, its member subobjects (also known as its "data members") are destructed in reverse order of their definition. After that, its base class subobjects are destructed in reverse order of the base-specifier-list:

                  class Foo : Bar, Baz
                  {
                      Quux x;
                      Quux y;
                  
                  public:
                  
                      ~Foo()
                      {
                      }  <--- y and x are destructed here,
                  };          followed by the Baz and Bar base class subobjects
                  

                  If an exception is thrown during the construction of one of Foo's subobjects, then all its previously constructed subobjects will be destructed before the exception is propagated. The Foo destructor, on the other hand, will not be executed, since the Foo object was never fully constructed.

                  Note that the destructor body is not responsible for destructing the data members themselves. You only need to write a destructor if a data member is a handle to a resource that needs to be released when the object is destructed (such as a file, a socket, a database connection, a mutex, or heap memory).

                  array elements

                  Array elements are destructed in descending order. If an exception is thrown during the construction of the n-th element, the elements n-1 to 0 are destructed before the exception is propagated.

                  temporary objects

                  A temporary object is constructed when a prvalue expression of class type is evaluated. The most prominent example of a prvalue expression is the call of a function that returns an object by value, such as T operator+(const T&, const T&). Under normal circumstances, the temporary object is destructed when the full-expression that lexically contains the prvalue is completely evaluated:

                  __________________________ full-expression
                                ___________  subexpression
                                _______      subexpression
                  some_function(a + " " + b);
                                            ^ both temporary objects are destructed here
                  

                  The above function call some_function(a + " " + b) is a full-expression because it is not part of a larger expression (instead, it is part of an expression-statement). Hence, all temporary objects that are constructed during the evaluation of the subexpressions will be destructed at the semicolon. There are two such temporary objects: the first is constructed during the first addition, and the second is constructed during the second addition. The second temporary object will be destructed before the first.

                  If an exception is thrown during the second addition, the first temporary object will be destructed properly before propagating the exception.

                  If a local reference is initialized with a prvalue expression, the lifetime of the temporary object is extended to the scope of the local reference, so you won't get a dangling reference:

                  {
                      const Foo& r = a + " " + b;
                                                ^ first temporary (a + " ") is destructed here
                      // ...
                  }  <--- second temporary (a + " " + b) is destructed not until here
                  

                  If a prvalue expression of non-class type is evaluated, the result is a value, not a temporary object. However, a temporary object will be constructed if the prvalue is used to initialize a reference:

                  const int& r = i + j;
                  

                  Dynamic objects and arrays

                  In the following section, destroy X means "first destruct X and then release the underlying memory". Similarly, create X means "first allocate enough memory and then construct X there".

                  dynamic objects

                  A dynamic object created via p = new Foo is destroyed via delete p. If you forget to delete p, you have a resource leak. You should never attempt to do one of the following, since they all lead to undefined behavior:

                  • destroy a dynamic object via delete[] (note the square brackets), free or any other means
                  • destroy a dynamic object multiple times
                  • access a dynamic object after it has been destroyed

                  If an exception is thrown during the construction of a dynamic object, the underlying memory is released before the exception is propagated. (The destructor will not be executed prior to memory release, because the object was never fully constructed.)

                  dynamic arrays

                  A dynamic array created via p = new Foo[n] is destroyed via delete[] p (note the square brackets). If you forget to delete[] p, you have a resource leak. You should never attempt to do one of the following, since they all lead to undefined behavior:

                  • destroy a dynamic array via delete, free or any other means
                  • destroy a dynamic array multiple times
                  • access a dynamic array after it has been destroyed

                  If an exception is thrown during the construction of the n-th element, the elements n-1 to 0 are destructed in descending order, the underlying memory is released, and the exception is propagated.

                  (You should generally prefer std::vector<Foo> over Foo* for dynamic arrays. It makes writing correct and robust code much easier.)

                  reference-counting smart pointers

                  A dynamic object managed by several std::shared_ptr<Foo> objects is destroyed during the destruction of the last std::shared_ptr<Foo> object involved in sharing that dynamic object.

                  (You should generally prefer std::shared_ptr<Foo> over Foo* for shared objects. It makes writing correct and robust code much easier.)

                  這篇關(guān)于C++中的對(duì)象銷毀的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

                  【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!

                  相關(guān)文檔推薦

                  In what ways do C++ exceptions slow down code when there are no exceptions thown?(當(dāng)沒有異常時(shí),C++ 異常會(huì)以何種方式減慢代碼速度?)
                  Why catch an exception as reference-to-const?(為什么要捕獲異常作為對(duì) const 的引用?)
                  When and how should I use exception handling?(我應(yīng)該何時(shí)以及如何使用異常處理?)
                  Scope of exception object in C++(C++中異常對(duì)象的范圍)
                  Catching exceptions from a constructor#39;s initializer list(從構(gòu)造函數(shù)的初始化列表中捕獲異常)
                  Difference between C++03 throw() specifier C++11 noexcept(C++03 throw() 說明符 C++11 noexcept 之間的區(qū)別)

                    <small id='cky1h'></small><noframes id='cky1h'>

                    • <bdo id='cky1h'></bdo><ul id='cky1h'></ul>
                      <legend id='cky1h'><style id='cky1h'><dir id='cky1h'><q id='cky1h'></q></dir></style></legend>
                        <tfoot id='cky1h'></tfoot>

                          <tbody id='cky1h'></tbody>

                          1. <i id='cky1h'><tr id='cky1h'><dt id='cky1h'><q id='cky1h'><span id='cky1h'><b id='cky1h'><form id='cky1h'><ins id='cky1h'></ins><ul id='cky1h'></ul><sub id='cky1h'></sub></form><legend id='cky1h'></legend><bdo id='cky1h'><pre id='cky1h'><center id='cky1h'></center></pre></bdo></b><th id='cky1h'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='cky1h'><tfoot id='cky1h'></tfoot><dl id='cky1h'><fieldset id='cky1h'></fieldset></dl></div>
                          2. 主站蜘蛛池模板: 三级网站在线 | 欧美精品在线播放 | 免费视频一区二区 | 国产精品亚洲综合 | 国产精品2区 | 伊人久久国产 | 操出白浆视频 | 亚洲欧美日韩一区二区三区四区 | 亚洲免费久久 | 五月网站 | 亚洲精品黄 | 国产色站| 免费久久久 | 无套内谢的新婚少妇国语播放 | 一区二区三区不卡视频 | 日韩在线观看免费 | 亚洲午夜在线 | 99色在线 | 一级片网址 | 国产高清久久 | 亚洲一区久久 | av一区二区在线观看 | 日本中文在线观看 | 国产视频一二三 | 成人免费在线视频观看 | 91视频精品 | 亚洲午夜精品 | 99热亚洲| 91久久国产综合久久91精品网站 | 久久高清免费视频 | 亚洲啪啪网 | 成人在线视频免费 | 免费性网站 | 韩国理论在线 | 欧美vieox另类极品 | 性视频在线 | 国产午夜在线 | 久久精品观看 | 日韩精品中文字幕在线观看 | 日韩综合精品 | 中文字幕日本 |