Re: [問題] auto_ptr_ref的功用
※ 引述《firose (guest也是也是也是也是也)》之銘言:
: ※ 引述《omomo34415 ( )》之銘言:
: : 請問auto_ptr的實作中為什麼要多定義
: : auto_ptr(auto_ptr_ref<T> rhs) throw() : ap(rhs.yp) {
: : }
: : auto_ptr& operator= (auto_ptr_ref<T> rhs) throw() { // new
: : reset(rhs.yp);
: : return *this;
: : }
: : template<class Y> operator auto_ptr_ref<Y>() throw() {
: : return auto_ptr_ref<Y>(release());
: : }
: : template<class Y> operator auto_ptr<Y>() throw() {
: : return auto_ptr<Y>(release());
: : }
: : 其他的CODE的在http://www.josuttis.com/libbook/util/autoptr.hpp.html
: : 看不太懂這些出現的時機。
: 因為 auto_ptr 的 ctor 是 explicit 的, 導致不能把一個 pointer 設給 auto_ptr
: 所以他才用一個 aotu_ptr_ref 讓指標可以做一次 user-define conversion 然後再
: 經由接受 auto_ptr_ref 的 auto_ptr constructor 讓這個行為可以 work.
不是的,auto_ptr_ref 並不是用在這種地方。
想像以下的程式碼:
auto_ptr<int> foo();
void bar()
{
...
auto_ptr<int> p_base = foo();
}
foo() 回傳的是一個暫時物件,但 auto_ptr 的 copy constructor 接受的卻是
non-const reference,這樣會造成編譯錯誤,因為暫時物件無法以 non-const
reference 的型式傳遞。解決之道是先把 auto_ptr 隱式轉型成 auto_ptr_ref,
然後讓 auto_ptr 的 constructor 可以接受 auto_ptr_ref 作為參數。
auto_ptr_ref 應該只用來做這類的轉換,而不應該拿來轉換一般的 pointer。
像以下的 code:
auto_ptr<int> p = new int(10);
在 VC 上,右邊的 int* 會被隱式轉換成 auto_ptr_ref,然後再送到 auto_ptr
的 constructor 中。這並不是正確的行為,VC 應該把 auto_ptr_ref 的
constructor 宣告為 explicit。
: 問題是 auto_ptr 為什麼要 explicit ? 因為如果他不這樣做的話, 然仍不能把指標
: 設給 auto_ptr , 因為它的 copy constructor/assignment 是接受 non-const 參考
這樣說就不對了
當你有一個 constructor 接受指標當作參數時
直接用指標去初始化並不會呼叫 copy constructor 也不會呼叫 copy assignement
template <typename T>
class auto_ptr {
public:
auto_ptr(T* p) {...} // 沒有 explicit
auto_ptr(auto_ptr<T>& p) {...} // copy constructor
};
auto_ptr<int> p = new int(10);
上述的程式碼會合法呼叫 auto_ptr<int>::auto_ptr<int>(int*),而不會去呼叫
copy constructor。
: 會這樣設計是因為它的內容呼叫 auto_ptr::release 這個函式會把內含指標 ap 設成 0
: 使 auto_ptr 可以順利把指標的擁有權轉移, 不會在 ~auto_ptr 刪除他, 所以 release
: 會是 non-const. 如果 copy constructor/assignment 接受 const reference 的話
: 是不能呼叫 non-const release 的, 所以它在這個設計裡必須是 non-const
auto_ptr 的 constructor 必需宣告為 explicit,否則當指標被隱式轉型成
auto_ptr 時,使用者會發現他在預期外的地方失去了指標的所有權:
void foo(auto_ptr<int> p); // foo 結束時,p 會自動被釋放
void bar()
{
int* p = new int(10);
foo(p); // 失去了 p 的所有權,但使用者一無所知!
delete p; // 重覆釋放 p,悲劇一場
}
使用 explicit constructor 可以讓使用者清楚地知道自己做了什麼事:
void bar()
{
int* p = new int(10);
foo( auto_ptr<int>(p) ); // 把 p 轉為 auto_ptr,我們已失去所有權
}
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 219.87.151.2
推
04/30 12:29, , 1F
04/30 12:29, 1F
→
04/30 12:30, , 2F
04/30 12:30, 2F
→
04/30 12:31, , 3F
04/30 12:31, 3F
推
04/30 12:51, , 4F
04/30 12:51, 4F
→
04/30 13:02, , 5F
04/30 13:02, 5F
→
04/30 13:03, , 6F
04/30 13:03, 6F
推
04/30 13:04, , 7F
04/30 13:04, 7F
→
04/30 13:11, , 8F
04/30 13:11, 8F
→
04/30 13:12, , 9F
04/30 13:12, 9F
→
04/30 13:13, , 10F
04/30 13:13, 10F
→
04/30 13:14, , 11F
04/30 13:14, 11F
→
04/30 13:15, , 12F
04/30 13:15, 12F
→
04/30 13:16, , 13F
04/30 13:16, 13F
推
04/30 13:20, , 14F
04/30 13:20, 14F
→
04/30 13:22, , 15F
04/30 13:22, 15F
→
04/30 13:23, , 16F
04/30 13:23, 16F
→
04/30 13:24, , 17F
04/30 13:24, 17F
→
04/30 13:25, , 18F
04/30 13:25, 18F
→
04/30 13:27, , 19F
04/30 13:27, 19F
→
04/30 13:28, , 20F
04/30 13:28, 20F
討論串 (同標題文章)
完整討論串 (本文為第 2 之 2 篇):