Re: [問題] 使用指標的時機

看板C_and_CPP作者 ( )時間4年前 (2019/09/13 06:33), 編輯推噓1(103)
留言4則, 2人參與, 4年前最新討論串4/6 (看更多)
※ 引述《PythonScript (Python)》之銘言: : 拍謝 真的是 C++ 新手 如果問了蠢問題請見諒 : 有翻過文章翻過書 但是還是不是很確定使用指標的時機 : 以我目前的理解 有錯再請提點 : 有 classA, classB 與 classC : classB 會產生 classA 的物件, 然後存在 classB 的屬性中 : 接著 classC 會去存取 classB, 也會使用 classB 中存 classA 的屬性 : 如果在 classB 中 classA objectA; : 未來某個時刻有可能會發生 classC 存取 classB 中存 classA 的屬性時 : 該屬性可能會消失或被取代 : 如果在 classB 中 classA* objectA = new objectA() : 就不會有上述描述情況的發生 : 可以這樣理解嗎? 你需要學習的不是指標這一語言機制的使用時機,而是物件導向的知識。 「未來某個時刻有可能會發生 classC 存取 classB 中存 classA 的屬性時, 該屬性可能會消失或被取代」 這段話乍聽之下會像是 GoF design patterns 的 strategy pattern, 但是往後看到這段就會發現其實你正處於自行摸索階段: 「如果在 classB 中 classA* objectA = new objectA(), 就不會有上述描述情況的發生」 從這段話來看,你決定是否使用指標,是為了避免 objectA 不見。 classA 的物件生命週期不受控於 classB, 不管 objectB 的狀態變得如何,你都希望 objectA 可以繼續存活於某處。 這在 OOD (物件導向設計) 階段,一般被模塑為 aggregation 關係,又叫 owns-a 關係。 但是 classB 並不控制 classA 的生命週期,所以你不該在 classB 中 new 出 objectA, 而是應該在其它地方 new 出 objectA,再把它透過 constructor 或 method 傳進去存。 你讓 classB 去把 objectA new 出來,這樣也應該讓 classB 負責 delete 它。 不然你的物件創造和銷毀機制就會散落在程式的不同地方,這樣就是個很糟的程式。 (以後你在 C++ 學到的 smart pointer 的確乍看之下會不是由 classB 負責銷毀, 但實際上它還是會因為 classB 的某些行為而間接引發銷毀,這意義上其實沒有變化。) 這種情況下聽起來要描述的是 composition 關係,又稱為 is-a-part-of 關係。 因為你是把 objectA 存到 objectB 裡面,不是想用的時候才 new 出來, 一旦用完就馬上把它銷毀掉,所以不會是 dependency 關係 (也叫 use-a 關係)。 從你描述的前後文來看,就像是 owns-a 和 is-a-part-of 關係的混合版。 這是因為你不熟悉物件導向,而程式語言給予太大的自由,導致你寫出了這種古怪程式。 熟悉物件導向的人一聽就會覺得渾身不對勁,然後會希望你能先去補足相關觀念。 實際上這段話在物件導向裡也是破壞封裝的一種行為: 「接著 classC 會去存取 classB,也會使用 classB 中存 classA 的屬性」 未來你學過以後就會知道這種事情應該避免。 語言機制如同一塊一塊形狀不同的積木,積木怎麼使用的確是可以隨心所欲。 但是經過諸多錯誤嘗試之後,你會發現要把積木組成某個你想像的樣子, 依循著某些規則去組合積木,可以讓結構最穩固,成功率也最高。 於是你漸漸就不會再隨便去組積木,而是依循一些你歸納出來的法則去組。 物件導向概念是前人諸多錯誤嘗試後傳承下來的一個經驗,學習它就能少走很多冤枉路。 比較遺憾的是 C++ 不是物件導向領域的主流程式語言, 相關書籍的範例程式碼大都不是以 C++ 寫成,可能是 Java、C# 等等。 你想學物件導向,可能還得稍微熟悉一下其它語言跟 C++ 的差異,並將它們轉成 C++。 要想在 C++ 開發物件導向程式,你得變得比現在更博學多聞。 : 其次就是 如果有個變數 variableA : 我有用指標變數 pointerA 指向 variableA : 這樣 variableA 應該是不會消失 直到我 delete 他 : 那如果有一系列的 variableA 變數指向它們 我想你這邊要說的是一系列的 pointerA。 : 我把它們整理成一個 vectorB : vectorB = vector<pointerA> : 如果怕 vectorB 弄丟 那需要再用一個 pointerB 指向 vectorB 嗎? 看起來你好像非常擔心把什麼東西弄丟。 然而若是你沒保管好 pointerB,你還是會把 pointerB 和 vectorB 一起弄丟。 這點物件導向分析和設計都可以讓你保管好它們,倒是不用太過於操心。 vector 這種東西一般不會用 poinier 去指向它,它只是一個低階資料。 正常來說它只會是 class 中的一個 private data member,所以是弄不丟的。 pointer 在 C++ 中是讓你動態抽換指涉對象的一個機制, 也是啟用多型和動態繫結機制的一個語言設施,並沒有防止你弄丟任何東西的功能。 要避免弄丟什麼,你要學的應該是如何規劃和設計你的程式。 -- Ling-hua Tseng Architect Research & Development Department Sky Mirror Technology Corporation -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 220.135.18.57 (臺灣) ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1568327595.A.E67.html

09/13 08:52, 4年前 , 1F
我一直覺得 C++ 的變數會突然消失
09/13 08:52, 1F

09/13 08:52, 4年前 , 2F
應該不是這麼一回事 應該是我有誤會什麼
09/13 08:52, 2F

09/13 08:52, 4年前 , 3F
我想應該是 pass by value 的問題
09/13 08:52, 3F

09/13 15:45, 4年前 , 4F
推:)
09/13 15:45, 4F
文章代碼(AID): #1TUiUhvd (C_and_CPP)
討論串 (同標題文章)
文章代碼(AID): #1TUiUhvd (C_and_CPP)