[問題] unique_ptr 接 raw ptr argument

看板C_and_CPP作者 (LoyalDog)時間10年前 (2016/01/25 20:17), 10年前編輯推噓5(5037)
留言42則, 6人參與, 最新討論串1/1
請問該如何把raw pointer 當argument丟給參數是unique_ptr的function呢? 實際情況約如下(太短就不貼其他地方了): void TestUP (unique_ptr<int*> temp) { **temp = 100; } int main (void) { int a {10}; TestUP (make_unique<int*>(&a)); return 0; } 上面這個結果Run得出來... 可是make_unique是14的東西,我要使用的環境只支援到11。 而且語意也很奇怪... 我要丟一個東西讓function修改,應該是丟指標就夠了,卻要丟掉指標的指標。 另外有嘗試過 unique_ptr<int>(&a) 可是在function裡面必須自己release,造成語意很奇怪。 請問有甚麼辦法解決呢? 謝謝~! ------- 至於為什麼要做這種事不直接丟Reference進去就好... 只能說是歷史因素... -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.133.8.225 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1453724241.A.C1A.html

01/25 20:28, , 1F
不好意思看不太懂你的意思... 不過有個問題...整份Code要遵守rule of zero,所以不能產生raw pointer (Orz 而一般變數沒辦法雙重取址,所以避不開Release的問題 Orz ※ 編輯: lovesnake (220.133.8.225), 01/25/2016 20:35:37

01/25 21:00, , 2F
我的意思是你根本傳錯參數,你的a是int而不是int*
01/25 21:00, 2F
我...還是不能理解 Orz 對不起理解力有問題。 我直接敘訴我碰到的問題好了 : 我的a是int,但是為了修改他我必須傳參照或指標進去,但現在傳參照的行為是禁止的, 所以我必須想辦法塞指標進去,可是又必須使用smart_ptr。 我現在碰到的狀況如上...

01/25 22:19, , 3F
TestUP(unique_ptr<int*>{new int*(&a)});
01/25 22:19, 3F
!! 居然忘了可以new一個。謝謝! 話說回到問題原點... 用參照或者指標傳進去就是為了不要產生臨時物件,但raw pointer丟給smart pointer 本身就違反這個行為...那這樣子的意義究竟在哪... 再把問題往上拉一個層次好了!! 原標準制定者的意圖是 : 讓呼叫端可以明顯看出哪個參數是輸入型參數、哪個參數是輸出型參數。 根據這個意圖制定者就制定了,傳參照是輸入型 (呼叫端看不出來名稱有變化), 傳指標是輸出型 (呼叫端要取址),也就是... func (a); func(&a); 這樣的差別,讓Code的可讀性上升。 就這樣的想法而言再搭配smart point,有什麼更好的方法可以達到這個目的呢? 謝謝! ※ 編輯: lovesnake (220.133.8.232), 01/26/2016 09:31:12

01/26 11:01, , 4F
請問你的輸出型參數是template嗎?
01/26 11:01, 4F

01/26 11:02, , 5F
還是你的輸出型參數是unique_ptr<int>or<int*>這種的?
01/26 11:02, 5F
我...依然不懂,突然覺得我該回去念小學了。 template <class T> void Func(std::unique_ptr<T> output) 這樣我該算是template還是第二種呢 Orz? 還是你的template是指其他的呢? 輸入端輸入的是一個變數(非參照或指標)作為輸出型參數,就像最上面的 int a。 所以裡面要接的應該是 unique_ptr<int> <<這樣比較符合語意。 但又會造成temporary object,而且又要自己 release,這又違反了C++的設計原則。 因此而煩惱Orz 還是不要理他輸出型的就直接傳raw pointer給他就好了? ((暴力解 ※ 編輯: lovesnake (220.133.8.232), 01/26/2016 11:22:25

01/26 11:20, , 6F
那行是原本 make_unique 被 inline 的結果,兩者意義一樣
01/26 11:20, 6F
原來如此! 長知識了 Orz 完全的C++新手 Orz ※ 編輯: lovesnake (220.133.8.232), 01/26/2016 11:23:12

01/26 12:32, , 7F
介面為何這樣設計? 有 unique_ptr 表示擁有權轉移吧?
01/26 12:32, 7F

01/26 12:33, , 8F
你說的那些code標準讓我覺得很奇怪...
01/26 12:33, 8F
目的是要讓呼叫端可以一眼就看出哪些會被改哪些不會被改。 我覺得立意很好只是實作上的方法...我太笨想不到 Orz

01/26 13:17, , 9F
我也覺得很怪,而且你Func這樣寫,output根本不能用
01/26 13:17, 9F

01/26 13:17, , 10F
要output可以用,parameter要是std::unique_ptr<T> &
01/26 13:17, 10F

01/26 13:18, , 11F
然後既然又是output,那你外面就只要create一個
01/26 13:18, 11F

01/26 13:19, , 12F
std::unique_ptr<T> output; 也不用初始化output,就直
01/26 13:19, 12F

01/26 13:20, , 13F
接傳進Func就好了
01/26 13:20, 13F
output為什麼會不能用呢@@? 不太確定是不是這個意思,不過如下: void TestUP (unique_ptr<int> temp) { std::cout << *temp << endl; *temp = 100; temp.release (); } int main (void) { int a{10}; TestUP (unique_ptr<int>(&a)); std::cout << a << endl; return 0; } 這是實際可以run的例子,但因為資料交給temporary的smart pointer管控了。 所以造成function裡面必須要release管控權,才不會隨著temp被消滅資料就消滅了。 而且還是消滅非動態配置的變數...程式就直接當掉這樣。 這樣語意超奇怪... 感覺比沒有用那個標準還糟糕了。 另外想請問,如果確定記憶體不是需要被管控的,那有強制要使用smart pointer嗎? 像是上面的程式的例子,區域變數本身交給smart pointer這個語意就已經超級奇怪了。 可是Func裡面如果用到raw pointer,又會有種...整份程式碼的Style不統一的feel。 恩...可能是我太刁鑽吧XD 碰到這種情況各位的選擇會是? ※ 編輯: lovesnake (220.133.8.232), 01/26/2016 13:54:30 ※ 編輯: lovesnake (220.133.8.232), 01/26/2016 13:54:44

01/26 14:07, , 14F
會不會被改應該是看 parameter 有沒有 const 吧
01/26 14:07, 14F

01/26 14:07, , 15F
用這些奇怪rule不如用個正常的ide直接顯示signature
01/26 14:07, 15F

01/26 14:08, , 16F
unique_ptr就是表示heap memory擁有權概念
01/26 14:08, 16F
我也贊成用IDE功能!!! 可是規定就是要遵守...

01/26 14:19, , 17F
因為那是output,如果你傳一個temporary object給TestUP
01/26 14:19, 17F

01/26 14:19, , 18F
呼叫TestUP的人要怎麼得到這個output結果?
01/26 14:19, 18F

01/26 14:22, , 19F
而且unique_ptr只應該用來綁new出來的物件
01/26 14:22, 19F

01/26 14:23, , 20F
他的確可以綁你的local variable,但你這樣用就會需要
01/26 14:23, 20F

01/26 14:24, , 21F
呼叫release
01/26 14:24, 21F

01/26 14:28, , 22F
如果你的output function都長這樣,那你就得必須都在裡
01/26 14:28, 22F

01/26 14:29, , 23F
面呼叫release
01/26 14:29, 23F

01/26 14:31, , 24F
如果TestUP的parameter是& http://ideone.com/Hd8MjU
01/26 14:31, 24F

01/26 14:32, , 25F
這樣外部的人可以拿到output,TestUP也不需要release
01/26 14:32, 25F

01/26 14:58, , 26F
如果不 RAII (因為去呼叫 release) 為何要用 unique_ptr ?
01/26 14:58, 26F
我之前對Rule of 0的理解是raw pointer就是萬惡,就是不能出現,一定得用Smart ptr。 不過看來是誤解,不是動態記憶體可以允許使用raw pointer...這樣對嗎? 然後我又有另外一個問題了... 如果今天傳進一個非動態記憶體的位置,被Function Delete掉要怎麼辦Orz? 有辦法在呼叫端就宣告 "這份記憶體是我的,我只是借你用,不準刪" << 這件事嗎? const沒辦法防止pointer被刪除。 似乎只有sheard_ptr 有辦法做到? 但一用上smart pointer就又有上面各位所提到的 問題出現...唉,為什麼不能用參照阿 .......... 覺得快崩潰了 Orz ※ 編輯: lovesnake (220.133.8.232), 01/26/2016 16:32:35

01/26 16:45, , 27F
既然有C++11支援,能用smart pointer就用,不行的話再用
01/26 16:45, 27F

01/26 16:46, , 28F
raw pointer
01/26 16:46, 28F

01/26 16:47, , 29F
一般來說,function不會去delete你的pointer,除非他本
01/26 16:47, 29F

01/26 16:47, , 30F
來就是拿來delete/release pointer
01/26 16:47, 30F

01/26 16:50, , 31F
我覺得你最大的問題,是當初那個function設計不良...
01/26 16:50, 31F
總是要想辦法防止寫function的人是__害程式當掉阿...

01/26 22:47, , 32F
你說的就reference啊 不能用到底是哪招
01/26 22:47, 32F

01/26 22:47, , 33F
快逃吧(?
01/26 22:47, 33F

01/26 22:57, , 34F
你都能使用smart pointer,為甚麼不能使用reference?
01/26 22:57, 34F

01/27 00:44, , 35F
其實我覺得會修改就用 pointer 是個合理準則, 避免 raw
01/27 00:44, 35F

01/27 00:44, , 36F
pointers 也是, 但訂這個規範的人應該要能解答你的問題
01/27 00:44, 36F

01/27 00:45, , 37F
要嘛有合理解法否則就需要有例外, 而不是死抱教條不放
01/27 00:45, 37F
後來問的解答是 1. 為了防止__ 2. 為了防止__ 3. 為了防止__ 然後底下Function會不會刪你非動態的記憶體... 只能祈禱下面沒有__。 覺得防了一個__,可是還是防不了第二個__。

01/27 01:54, , 38F
new 出來的才需要特別關照。如果連這種被管理會自動釋放
01/27 01:54, 38F

01/27 01:54, , 39F
的指標,引用他的位置都不能用pointer還叫C++ programm
01/27 01:54, 39F

01/27 01:54, , 40F
ing? 其實是你曲解教義吧。
01/27 01:54, 40F
剛學C++,才疏學淺,已經確實了解了~

01/27 14:10, , 41F
你確定你了解 pointer / reference ?
01/27 14:10, 41F
我...好吧我不確定我了解 ※ 編輯: lovesnake (220.133.8.225), 01/27/2016 15:56:05

01/27 17:02, , 42F
所以那些function,你只能用,而不能改,這樣對嗎?
01/27 17:02, 42F
我自己應該不能改,要發Issue請當初寫的人改。 ※ 編輯: lovesnake (220.133.8.225), 01/28/2016 11:54:23
文章代碼(AID): #1MfX9HmQ (C_and_CPP)