2012-08-28 87 views
2

指針如何與面向對象編程的概念一起工作?指針和麪向對象編程

據我瞭解(請認識到,我被歸類爲ID-10T),OOP的主要原則是包含在課堂中的遏制和管理責任(記憶/實施等);但是當一個對象的方法返回一個指針時,好像我們是'彈出'的對象。現在,有人可能需要擔心:

  1. 是否他們應該刪除指針的關聯對象?
  2. 但是如果班級仍然需要這個對象呢?
  3. 他們可以改變對象嗎?如果是這樣,怎麼樣? (我承認const可能會解決這個問題)
  4. 等等...

看來對象的用戶現在需要知道更多關於如何類作品和什麼類預計用戶。這感覺就像是一隻「貓沒有包裝」的情景,似乎在OOP面前拍了拍。

注:我注意到,這是一個獨立於語言的問題;但是,在C++環境中工作時,系統提示我提問。

+3

在C++ 11中,原始指針只能用於表示無所有權。 –

+1

我會研究「const vs nonconst」,「指針vs參考」,「左值vs右值」和「std :: unique_ptr」,「std :: shared_ptr」和「std :: weak_ptr」。人們抱怨C++中存在複雜的內存管理問題,這些問題在其他語言(如Java和C#)中被渲染 - 然而還有一個好處:性能。 –

回答

5

你描述的是所有權問題。這些是正交的(即獨立的,你可以沒有其他的或甚至兩者)來面向對象。如果你不使用OOP和Pug結構的指針,你也會遇到同樣的問題。如果您使用OOP但不知何故解決問題,則不存在此問題。你可以(嘗試)使用更多的OOP或以其他方式解決它。

他們也是垂直指針的使用(除非你尼特挑,延長指針的定義)。例如,如果兩個單獨的位置將索引保存到數組中並進行變異,調整大小並最終刪除數組,則會出現相同的問題。

在C++中,通常的解決辦法是選擇正確的智能指針類型(例如當你想共享對象時返回一個共享指針,或者表示獨佔所有權的唯一指針)以及大量的文檔。實際上,後者是任何語言的關鍵組成部分。

一個OOP- 相關你可以做的事情是幫助這個封裝(當然,你可以在沒有OOP的情況下使用encaptulation)。例如,不要公開對象,只公開在查詢引擎下查詢對象的方法。或者不要暴露原始指針,只暴露智能指針。

+0

沒有提及引用? –

+0

@MooingDuck說實話,我沒有強烈的意見,應該如何在這些情況下使用引用。我唯一的猜測就是使用它們來指示非擁有的臨時訪問? (另外,我的答案中有一半以上是語言不可知的,很多語言甚至沒有*引用。) – delnan

0

根據我的理解和經驗,它通常圍繞着你正在嘗試做的事情以及使用指針(例如C++ vs Objective-C)的語言

雖然用C++術語來說,我發現最好是通過引用返回一個對智能指針的引用(如std::shared_ptr)(根據情況甚至可以是const引用),或者直接隱藏該類中的指針,並且如果它需要被其外部的某個東西訪問或使用,則使用一個getter方法,該方法複製指針並返回該指針,或者返回對指針的引用(授予,AFAIK ref-to-ptr只有在C++中才有可能)。如果有人不知道你不應刪除裁判對PTR在大多數情況下(當然,如果它的重新分配由內部類處理),你應該三思而後行不論他們是否是準備好在你的團隊中做C++的東西。

是很常見的,只是使用公共引用類的成員,如果他們可以堆棧中分配(即,如果它們不會佔用太多的內存),而內部管理堆中分配的對象。如果您需要在類的外部設置類成員,可以使用一個採用所需值的set方法,而不是直接訪問它。

+1

我能想到一個類返回一個原始指針的唯一原因是它需要通過NULL返回一個非擁有的「引用」給一個可能不存在的成員。在所有其他情況下,應該返回一個引用,智能指針或值。沒有理由返回對原始指針的引用。 –

+0

@MooingDuck - 安全關鍵代碼要求。 –

+0

@MooingDuck - 單身呢?我寧願能夠通過引用指針來管理共享實例,而不是單獨處理原始指針。這樣,當我完成它時,我不必擔心釋放內存。 – zeboidlund

1

對於初學者...您不能有沒有指針或 引用的多態性。在C++中,傳統上,對象被複制,並具有(大部分爲 )自動存儲持續時間。但複製不適用於 多態對象—他們傾向於切片。 OO也經常意味着身份,這反過來意味着你不想複製。所以 解決方案是爲動態分配對象,並圍繞指針傳遞 。你跟他們做的是設計的一部分:

如果對象是邏輯上的另一個對象的一部分,則該對象是 負責其生命週期,並接受指針 應採取措施的對象,以確保他們不對象消失後不再使用它。 (請注意,即使在有垃圾收集的 語言中也是如此,只要您有指向它的指針,對象不會消失,但一旦擁有的對象無效,擁有的對象 也可能變得無效,垃圾收集器不會 回收內存將不能保證您指向的對象是 可用的事實。)

如果對象是一個一流的實體本身,而不是 邏輯的一部分另一個對象,那麼它應該自己照顧 。同樣,如果它不再存在(或變得無效),則可以持有指向它的其他對象必須是 。使用 觀察者模式是通常的解決方案。當我開始使用C++時, 是一種「關係管理」的方式,某種類型的 管理類在其中註冊了關係,並且其中 假定確保一切正常。實際上,他們 要麼沒有工作,要麼只是簡單的觀察者 模式,你今天沒有聽到更多的消息。

大多數情況下,您的確切問題是每個班級必須爲其每個功能建立的合同的一部分。對於真實的OO 類(實體對象),您應該永遠不要刪除它們:那就是 那裏有業務,而不是您的。但也有例外:如果您使用交易處理 ,例如,已刪除的對象無法回滾,因此,當對象決定刪除自己時,通常會將此事實註冊到事務管理器,此事務將刪除它作爲 提交的一部分,一旦確定回滾將不是必需的。由於 用於更改對象,這是一個合同問題:在很多應用程序中,都有映射對象,用於將某種外部標識符映射到對象。有了目標,經常能夠修改對象的 。