2010-09-14 51 views
0

這是C++透視圖中的一般設計問題。我有一個包含2個其他類的對象的容器類。如何將Contained類調用包含類的成員函數 - C++中的成分

從容器類中,我們可以調用包含的類對象的方法,「因爲我們已經處理了包含的類對象」,例如objContainedClass1-> SomeMthod();

但我想知道包含的類對象(objContainedClass1)將如何訪問容器類的方法。

我能想到的以下方式:

  1. 容器類對象傳遞指針本身(該指針),以所包含的類的構造函數。使用這個指針,包含的類可以訪問容器類的方法。

  2. 將容器類中的某些函數設置爲靜態。

有沒有更多的想法呢?

謝謝

回答

6

不要,通常這是一個糟糕的設計,需要了解其容器。通常這意味着你打破了單一責任原則。

+2

我真的不知道雙向關聯與單一責任原則有什麼關係。如果不是強制性的,我可以想到很多情況下雙向關聯是有用的。例如,在樹結構中(參見Composite),在節點中引用父對象通常很有用。 – 2010-09-14 14:08:29

+1

這取決於情況。在知道其他節點的圖中並不是什麼大不了的事情。但大多數情況下,這是一個壞主意。套接字不應該知道它們所在的FD_SET,如果你的實現是這樣的話,那是因爲你的套接字做了不止一件事,也就是違反了SRP。所以它不是自動的,不是10次,但不是正確的做法。大多數時候,當我看到容器正在成爲一個容器,並在其他地方做一些應該包含另一個同伴的東西時。 – stonemetal 2010-09-14 14:15:35

+0

我希望我可以刪除我的downvote,因爲你的評論現在增加了我認爲在你的答案中缺乏的細微差別,但它不再可能:(。 – 2010-09-14 14:43:36

2

兩種方式都可以用於不同的目的。如果你只需要調用靜態方法,#2就可以。但是如果你需要訪問容器類的實例方法,你需要有容器類的指針,所以#1就是這樣。

在你需要通用解決方案的情況下,實現觀察者模式。在這種情況下,包含的類不知道容器的任何內容,它只是在必要時引發事件。

+0

爲了實現觀察者模式,特別是在提高事件時,不包含對象需要調用容器的類函數嗎?即我們回到原來的問題。 – 2016-01-02 13:14:37

1

有很多不好的選擇。

如果容器類不在其外部使用,則可以將其包含的類作爲容器類的一部分。

你可以讓容器成爲包含類的好友(yuck)。

您可以將引用或boost :: shared_ptr傳遞給容器而不是原始指針。最好的方法取決於每個的生命週期。如果可以的話,避免使用原始指針。

我實際上試圖做的是隔離包含對象需要使用的容器方法的接口(例如IContainerCallback),並將它用作兩者之間的鏈接。因此,包含的對象只通過與容器的實現分離的接口類間接引用容器。

0
  • 將容器類中的某些函數設置爲靜態。

這就是所謂的「再見OOP!」選項,我儘量不要使用它。

  • 容器類對象傳遞指針本身(該指針),以所包含的類的構造函數。使用這個指針,包含的類可以訪問容器類的方法。

前提是含有類實現一個接口,包含的類只知道界面,我個人看不出有什麼問題。其實這正是我自己做的。顯然,人們必須知道該方法的陷阱,例如,包含對象在銷燬後者(或容器處於中間狀態時的任何其他時刻)期間調用容器的方法。

爲了進一步分離包含的類和包含類,事件或消息也可以使用。包含的對象不知道它們包含在哪裏,而是發送消息。在創建包含對象時包含對象將自己註冊爲從它們接收消息。 (1)一些消息傳遞框架,(2)由於C++的靜態特性而非實現,以及(3)還需要額外的文檔級別,因爲類的接口現在包括消息傳遞。

否則,請仔細想想爲什麼包含的對象需要調用容器的方法。難道你需要將容器的一些通用功能分成第三類嗎?如果包含的對象確實是活動對象並且是系統中事件的邏輯源,那麼您可能確實需要一些基本的事件/消息傳遞系統,以允許容器有效地輪詢/監視包含對象中的狀態更改。

-1

不要。容器類的責任是包含事物,沒有別的。如果您需要您的容器類根據其中包含的內容採取行動,請讓第三個對象執行這些操作。例如,我假設你正在重新安排或根據類的內容修改類的集合。不要在包含的類中嘗試這樣做,而是在使用容器作爲依賴項的類中執行此操作。