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

為什么不在 C++ 中對所有內容都使用指針?

Why not use pointers for everything in C++?(為什么不在 C++ 中對所有內容都使用指針?)
本文介紹了為什么不在 C++ 中對所有內容都使用指針?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

限時送ChatGPT賬號..

假設我定義了一些類:

class Pixel {
    public:
      Pixel(){ x=0; y=0;};
      int x;
      int y;
}

然后使用它編寫一些代碼.我為什么要執行以下操作?

Then write some code using it. Why would I do the following?

Pixel p;
p.x = 2;
p.y = 5;

來自 Java 世界,我一直在寫:

Coming from a Java world I always write:

Pixel* p = new Pixel();
p->x = 2;
p->y = 5;

他們基本上做同樣的事情,對吧?一個在堆棧上,而另一個在堆上,所以我稍后必須刪除它.兩者之間有什么根本區別嗎?為什么我應該更喜歡一個?

They basically do the same thing, right? One is on the stack while the other is on the heap, so I'll have to delete it later on. Is there any fundamental difference between the two? Why should I prefer one over the other?

推薦答案

是的,一個在堆棧上,另一個在堆上.有兩個重要區別:

Yes, one is on the stack, the other on the heap. There are two important differences:

  • 首先,顯而易見但不太重要的一點是:堆分配很慢.堆棧分配很快.
  • 第二,更重要的是RAII.因為堆棧分配的版本會自動清理,所以很有用.它的析構函數會被自動調用,這使您可以保證該類分配的任何資源都得到清理.這基本上是您在 C++ 中避免內存泄漏的方法.您可以通過從不自己調用 delete 來避免它們,而是將其包裝在堆棧分配的對象中,這些對象在內部調用 delete,通常在它們的析構函數中.如果您嘗試手動跟蹤所有分配,并在正確的時間調用 delete,我向您保證每 100 行代碼至少會發生內存泄漏.
  • First, the obvious, and less important one: Heap allocations are slow. Stack allocations are fast.
  • Second, and much more important is RAII. Because the stack-allocated version is automatically cleaned up, it is useful. Its destructor is automatically called, which allows you to guarantee that any resources allocated by the class get cleaned up. This is essentialy how you avoid memory leaks in C++. You avoid them by never calling delete yourself, instead wrapping it in stack-allocated objects which call delete internally, typicaly in their destructor. If you attempt to manually keep track of all allocations, and call delete at the right times, I guarantee you that you'll have at least a memory leak per 100 lines of code.

作為一個小例子,考慮以下代碼:

As a small example, consider this code:

class Pixel {
public:
  Pixel(){ x=0; y=0;};
  int x;
  int y;
};

void foo() {
  Pixel* p = new Pixel();
  p->x = 2;
  p->y = 5;

  bar();

  delete p;
}

很無辜的代碼,對吧?我們創建一個像素,然后調用一些不相關的函數,然后刪除該像素.是否存在內存泄漏?

Pretty innocent code, right? We create a pixel, then we call some unrelated function, and then we delete the pixel. Is there a memory leak?

答案是可能".如果 bar 拋出異常會發生什么?delete 永遠不會被調用,像素永遠不會被刪除,我們會泄漏內存.現在考慮這個:

And the answer is "possibly". What happens if bar throws an exception? delete never gets called, the pixel is never deleted, and we leak memory. Now consider this:

void foo() {
  Pixel p;
  p.x = 2;
  p.y = 5;

  bar();
}

這不會泄漏內存.當然,在這個簡單的例子中,一切都在堆棧上,所以它會自動清理,但即使 Pixel 類在內部進行了動態分配,也不會泄漏.Pixel 類將簡單地被賦予一個析構函數來刪除它,無論我們如何離開 foo 函數,都會調用這個析構函數.即使我們因為 bar 拋出異常而離開它.以下稍微做作的示例顯示了這一點:

This won't leak memory. Of course in this simple case, everything is on the stack, so it gets cleaned up automatically, but even if the Pixel class had made a dynamic allocation internally, that wouldn't leak either. The Pixel class would simply be given a destructor that deletes it, and this destructor would be called no matter how we leave the foo function. Even if we leave it because bar threw an exception. The following, slightly contrived example shows this:

class Pixel {
public:
  Pixel(){ x=new int(0); y=new int(0);};
  int* x;
  int* y;

  ~Pixel() {
    delete x;
    delete y;
  }
};

void foo() {
  Pixel p;
  *p.x = 2;
  *p.y = 5;

  bar();
}

Pixel 類現在在內部分配了一些堆內存,但是它的析構函數負責清理它,所以當使用這個類時,我們不必擔心它.(我應該提一下,這里的最后一個例子被簡化了很多,以顯示一般原則.如果我們實際使用這個類,它也包含幾個可能的錯誤.如果 y 的分配失敗,x 永遠不會被釋放, 如果 Pixel 被復制,我們最終會導致兩個實例都試圖刪除相同的數據.因此,請保留最后一個示例.實際代碼有點棘手,但它顯示了總體思路)

The Pixel class now internally allocates some heap memory, but its destructor takes care of cleaning it up, so when using the class, we don't have to worry about it. (I should probably mention that the last example here is simplified a lot, in order to show the general principle. If we were to actually use this class, it contains several possible errors too. If the allocation of y fails, x never gets freed, and if the Pixel gets copied, we end up with both instances trying to delete the same data. So take the final example here with a grain of salt. Real-world code is a bit trickier, but it shows the general idea)

當然,相同的技術可以擴展到內存分配以外的其他資源.例如,它可用于保證文件或數據庫連接在使用后關閉,或者釋放線程代碼的同步鎖.

Of course the same technique can be extended to other resources than memory allocations. For example it can be used to guarantee that files or database connections are closed after use, or that synchronization locks for your threading code are released.

這篇關于為什么不在 C++ 中對所有內容都使用指針?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

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

相關文檔推薦

Difference between std::reference_wrapper and simple pointer?(std::reference_wrapper 和簡單指針的區別?)
Difference between const. pointer and reference?(常量之間的區別.指針和引用?)
How to access the contents of a vector from a pointer to the vector in C++?(c++ - 如何從指向向量的指針訪問向量的內容?)
Meaning of *amp; and **amp; in C++(*amp; 的含義和**amp;在 C++ 中)
Why can#39;t I do polymorphism with normal variables?(為什么我不能對普通變量進行多態?)
Dereferencing deleted pointers always result in an Access Violation?(取消引用已刪除的指針總是會導致訪問沖突?)
主站蜘蛛池模板: 国产成人精品a视频一区www | 日本不卡一区二区三区 | 浴室洗澡偷拍一区二区 | 自拍在线 | 日本在线视频一区二区 | 欧美成人一区二区三区片免费 | 国产精品一二三区 | 日韩高清av | 久久久久国色av免费观看性色 | 日韩三级电影一区二区 | 国产精品高潮呻吟久久av黑人 | 中文字幕视频在线看5 | 欧美亚洲一区二区三区 | 欧美一区二区三区四区视频 | 久久久久国产精品一区 | www.99re| 亚洲综合色视频在线观看 | 久久久久网站 | 久久久久久久99 | 国产免费播放视频 | 成年人精品视频在线观看 | 国产观看 | 99精品国产一区二区青青牛奶 | 韩日在线| 91偷拍精品一区二区三区 | 五月激情综合 | 久久777 | 国产一区二区三区日韩 | 国产资源一区二区三区 | 日本久久久久久久久 | 一区二区久久 | 久久一区二区三区四区五区 | 四虎永久免费在线 | 国产精品久久久一区二区三区 | 91观看| 国产成人99久久亚洲综合精品 | 日韩国产在线观看 | 国产一区亚洲 | 99中文字幕| 国产精品久久久久久妇女 | 亚洲一区二区三区视频 |