程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 實戰c++中的智能指針unique_ptr系列-- unique_ptr的operator=、operator bool、reset、swap、get等介紹

實戰c++中的智能指針unique_ptr系列-- unique_ptr的operator=、operator bool、reset、swap、get等介紹

編輯:C++入門知識

實戰c++中的智能指針unique_ptr系列-- unique_ptr的operator=、operator bool、reset、swap、get等介紹


既然打算把unique_ptr寫一個系列,就要詳盡一點,有些內容也許在vector的時候有個涉及,但是現在還是再談論一番。

我們要把unique_ptr看做一個類,廢話了,它當然是一個類。所以這個類肯定也重載了賦值運算符,即operator=。現在就開始看看operator=在unique_ptr中的使用:
官方描述如下:

move assignment (1) 
unique_ptr& operator= (unique_ptr&& x) noexcept;
assign null pointer (2) 
unique_ptr& operator= (nullptr_t) noexcept;
type-cast assignment (3)    
template 
  unique_ptr& operator= (unique_ptr&& x) noexcept;
copy assignment (deleted!) (4)  
unique_ptr& operator= (const unique_ptr&) = delete;

這裡簡要實例:

#include 
#include 

int main () {
  std::unique_ptr foo;
  std::unique_ptr bar;

  foo = std::unique_ptr(new int (101));  // rvalue

  bar = std::move(foo);                       // using std::move

  std::cout << "foo: ";
  if (foo) std::cout << *foo << '\n'; else std::cout << "empty\n";

  std::cout << "bar: ";
  if (bar) std::cout << *bar << '\n'; else std::cout << "empty\n";

  return 0;
}

輸出:
foo: empty
bar: 101
唯一需要說明的就是std::move後,foo變為了empty,如果對於這個empty再做一些操作的話,就會導致一些災難了。

其實說白了,就是摧毀原來的指針,並把新指針指向原來指針指向的對象。。。。

那麼接下來reset方法即出廠了,到達上面的效果:

#include 
#include 

int main () {
  std::unique_ptr up;  // empty

  up.reset (new int);       // takes ownership of pointer
  *up=5;
  std::cout << *up << '\n';

  up.reset (new int);       // deletes managed object, acquires new pointer
  *up=10;
  std::cout << *up << '\n';

  up.reset();               // deletes managed object

  return 0;
}
//輸出:
5
10

swap
我們在vector裡就接觸過,unique_ptr同樣具有這個成員函數:
Exchanges the contents of the unique_ptr object with those of x, transferring ownership of any managed object between them without destroying either.

最重要的就是沒有銷毀任何一個:

#include 
#include 

int main () {
  std::unique_ptr foo (new int(10));
  std::unique_ptr bar (new int(20));

  foo.swap(bar);

  std::cout << "foo: " << *foo << '\n';
  std::cout << "bar: " << *bar << '\n';

  return 0;
}
//輸出
foo為20
bar為10

get
get很簡單,唯一需要注意的就是:
Notice that a call to this function does not make unique_ptr release ownership of the pointer (i.e., it is still responsible for deleting the managed data at some point). Therefore, the value returned by this function shall not be used to construct a new managed pointer.

最主要的一點就是,智能指針沒有釋放,即沒有失去所有權:

#include 
#include 

int main () {
                                           // foo   bar    p
                                           // ---   ---   ---
  std::unique_ptr foo;                // null
  std::unique_ptr bar;                // null  null
  int* p = nullptr;                        // null  null  null

  foo = std::unique_ptr(new int(10)); // (10)  null  null
  bar = std::move(foo);                    // null  (10)  null
  p = bar.get();                           // null  (10)  (10)
  *p = 20;                                 // null  (20)  (20)
  p = nullptr;                             // null  (20)  null

  foo = std::unique_ptr(new int(30)); // (30)  (20)  null
  p = foo.release();                       // null  (20)  (30)
  *p = 40;                                 // null  (20)  (40)

  std::cout << "foo: ";
  if (foo) std::cout << *foo << '\n'; else std::cout << "(null)\n";

  std::cout << "bar: ";
  if (bar) std::cout << *bar << '\n'; else std::cout << "(null)\n";

  std::cout << "p: ";
  if (p) std::cout << *p << '\n'; else std::cout << "(null)\n";
  std::cout << '\n';

  delete p;   // the program is now responsible of deleting the object pointed to by p
              // bar deletes its managed object automatically

  return 0;
}

即上面代碼提到的,p = bar.get(); 後,bar並非被釋放,也就相當於指針p和智能指針bar共同管理一個對象,所以就*p做的一切,都會反應到bar指向的對象上。

這段代碼有了一個與get相對比的方法:release

release
不必多說:
This call does not destroy the managed object, but the unique_ptr object is released from the responsibility of deleting the object. Some other entity must take responsibility for deleting the object at some point.
重點就是一句話:智能指針被釋放。

#include 
#include 

int main () {
  std::unique_ptr auto_pointer (new int);
  int * manual_pointer;

  *auto_pointer=10;

  manual_pointer = auto_pointer.release();
  // (auto_pointer is now empty)

  std::cout << "manual_pointer points to " << *manual_pointer << '\n';

  delete manual_pointer;

  return 0;
}

最後了,再介紹一個operator bool吧,即unique_ptr有這樣一個成員函數,來檢查是否為空:

#include 
#include 


int main () {
  std::unique_ptr foo;
  std::unique_ptr bar (new int(12));

  if (foo) std::cout << "foo points to " << *foo << '\n';
  else std::cout << "foo is empty\n";

  if (bar) std::cout << "bar points to " << *bar << '\n';
  else std::cout << "bar is empty\n";

  return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved