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

作者: tinlans ( )   2019-09-13 06:33:12
※ 引述《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++ 中是讓你動態抽換指涉對象的一個機制,
也是啟用多型和動態繫結機制的一個語言設施,並沒有防止你弄丟任何東西的功能。
要避免弄丟什麼,你要學的應該是如何規劃和設計你的程式。
作者: PythonScript (Python)   2019-09-13 08:52:00
我一直覺得 C++ 的變數會突然消失應該不是這麼一回事 應該是我有誤會什麼我想應該是 pass by value 的問題
作者: VictorTom (鬼翼&娃娃魚)   2019-09-13 15:45:00
推:)

Links booklink

Contact Us: admin [ a t ] ucptt.com