看板 C_and_CPP 關於我們 聯絡資訊
請問該如何把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
Caesar08: http://ideone.com/v4RMMs 01/25 20:28
不好意思看不太懂你的意思... 不過有個問題...整份Code要遵守rule of zero,所以不能產生raw pointer (Orz 而一般變數沒辦法雙重取址,所以避不開Release的問題 Orz ※ 編輯: lovesnake (220.133.8.225), 01/25/2016 20:35:37
Caesar08: 我的意思是你根本傳錯參數,你的a是int而不是int* 01/25 21:00
我...還是不能理解 Orz 對不起理解力有問題。 我直接敘訴我碰到的問題好了 : 我的a是int,但是為了修改他我必須傳參照或指標進去,但現在傳參照的行為是禁止的, 所以我必須想辦法塞指標進去,可是又必須使用smart_ptr。 我現在碰到的狀況如上...
firose: TestUP(unique_ptr<int*>{new int*(&a)}); 01/25 22:19
!! 居然忘了可以new一個。謝謝! 話說回到問題原點... 用參照或者指標傳進去就是為了不要產生臨時物件,但raw pointer丟給smart pointer 本身就違反這個行為...那這樣子的意義究竟在哪... 再把問題往上拉一個層次好了!! 原標準制定者的意圖是 : 讓呼叫端可以明顯看出哪個參數是輸入型參數、哪個參數是輸出型參數。 根據這個意圖制定者就制定了,傳參照是輸入型 (呼叫端看不出來名稱有變化), 傳指標是輸出型 (呼叫端要取址),也就是... func (a); func(&a); 這樣的差別,讓Code的可讀性上升。 就這樣的想法而言再搭配smart point,有什麼更好的方法可以達到這個目的呢? 謝謝! ※ 編輯: lovesnake (220.133.8.232), 01/26/2016 09:31:12
Caesar08: 請問你的輸出型參數是template嗎? 01/26 11:01
Caesar08: 還是你的輸出型參數是unique_ptr<int>or<int*>這種的? 01/26 11:02
我...依然不懂,突然覺得我該回去念小學了。 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
firose: 那行是原本 make_unique 被 inline 的結果,兩者意義一樣 01/26 11:20
原來如此! 長知識了 Orz 完全的C++新手 Orz ※ 編輯: lovesnake (220.133.8.232), 01/26/2016 11:23:12
BlazarArc: 介面為何這樣設計? 有 unique_ptr 表示擁有權轉移吧? 01/26 12:32
BlazarArc: 你說的那些code標準讓我覺得很奇怪... 01/26 12:33
目的是要讓呼叫端可以一眼就看出哪些會被改哪些不會被改。 我覺得立意很好只是實作上的方法...我太笨想不到 Orz
Caesar08: 我也覺得很怪,而且你Func這樣寫,output根本不能用 01/26 13:17
Caesar08: 要output可以用,parameter要是std::unique_ptr<T> & 01/26 13:17
Caesar08: 然後既然又是output,那你外面就只要create一個 01/26 13:18
Caesar08: std::unique_ptr<T> output; 也不用初始化output,就直 01/26 13:19
Caesar08: 接傳進Func就好了 01/26 13:20
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
BlazarArc: 會不會被改應該是看 parameter 有沒有 const 吧 01/26 14:07
BlazarArc: 用這些奇怪rule不如用個正常的ide直接顯示signature 01/26 14:07
BlazarArc: unique_ptr就是表示heap memory擁有權概念 01/26 14:08
我也贊成用IDE功能!!! 可是規定就是要遵守...
Caesar08: 因為那是output,如果你傳一個temporary object給TestUP 01/26 14:19
Caesar08: 呼叫TestUP的人要怎麼得到這個output結果? 01/26 14:19
Caesar08: 而且unique_ptr只應該用來綁new出來的物件 01/26 14:22
Caesar08: 他的確可以綁你的local variable,但你這樣用就會需要 01/26 14:23
Caesar08: 呼叫release 01/26 14:24
Caesar08: 如果你的output function都長這樣,那你就得必須都在裡 01/26 14:28
Caesar08: 面呼叫release 01/26 14:29
Caesar08: 如果TestUP的parameter是& http://ideone.com/Hd8MjU 01/26 14:31
Caesar08: 這樣外部的人可以拿到output,TestUP也不需要release 01/26 14:32
firose: 如果不 RAII (因為去呼叫 release) 為何要用 unique_ptr ? 01/26 14:58
我之前對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
Caesar08: 既然有C++11支援,能用smart pointer就用,不行的話再用 01/26 16:45
Caesar08: raw pointer 01/26 16:46
Caesar08: 一般來說,function不會去delete你的pointer,除非他本 01/26 16:47
Caesar08: 來就是拿來delete/release pointer 01/26 16:47
Caesar08: 我覺得你最大的問題,是當初那個function設計不良... 01/26 16:50
總是要想辦法防止寫function的人是__害程式當掉阿...
BlazarArc: 你說的就reference啊 不能用到底是哪招 01/26 22:47
BlazarArc: 快逃吧(? 01/26 22:47
Caesar08: 你都能使用smart pointer,為甚麼不能使用reference? 01/26 22:57
uranusjr: 其實我覺得會修改就用 pointer 是個合理準則, 避免 raw 01/27 00:44
uranusjr: pointers 也是, 但訂這個規範的人應該要能解答你的問題 01/27 00:44
uranusjr: 要嘛有合理解法否則就需要有例外, 而不是死抱教條不放 01/27 00:45
後來問的解答是 1. 為了防止__ 2. 為了防止__ 3. 為了防止__ 然後底下Function會不會刪你非動態的記憶體... 只能祈禱下面沒有__。 覺得防了一個__,可是還是防不了第二個__。
ronin728: new 出來的才需要特別關照。如果連這種被管理會自動釋放 01/27 01:54
ronin728: 的指標,引用他的位置都不能用pointer還叫C++ programm 01/27 01:54
ronin728: ing? 其實是你曲解教義吧。 01/27 01:54
剛學C++,才疏學淺,已經確實了解了~
bibo9901: 你確定你了解 pointer / reference ? 01/27 14:10
我...好吧我不確定我了解 ※ 編輯: lovesnake (220.133.8.225), 01/27/2016 15:56:05
Caesar08: 所以那些function,你只能用,而不能改,這樣對嗎? 01/27 17:02
我自己應該不能改,要發Issue請當初寫的人改。 ※ 編輯: lovesnake (220.133.8.225), 01/28/2016 11:54:23