2010-09-23 56 views
0

我需要對我的類Foo的元素提供某種操作。這個操作是特定的和奇怪的,我不想讓它成爲一個成員函數。另一方面,它在類內部工作,我不想公開。提供(可選)功能和封裝之間的衝突?

下面是類:

class Foo { 
    typedef std::map<int,double> VecElem; 
    std::vector<VecElem> vec_; 
public: 
    void Insert(std::size_t index0, int index1, double d); 
    // ... other essential functions 
}; 

void Foo::Insert(std::size_t index0, int index1, double d) { 
    vec_[index0][index1] = d; 
} 

我需要支持的操作是映射到目前爲止插入到新索引的每個元件的index1,根據給定的舊到新的索引圖:

void MapIndex1(const std::map<std::size_t,std::size_t>& old_to_new); 

鑑於Foo當前如何保存它的元素,這意味着內部數據的全面的調整,但這不應該暴露給用戶。但它也不應該是一個成員函數。

這是非成員函數friend的典型案例嗎?還有其他的可能嗎?我不太喜歡friend非成員函數的概念,因爲這個奇怪的函數(它可能只是臨時必需的,作爲解決某個問題的一種方法)仍然需要在「官方」類的主體內部提及(這是應該永遠不會改變)。但我想我無法解決這個問題?

+3

我不會太擔心添加/刪除朋友。 「官方」班級機構永遠不應該改變的規則受到一個規則的啓發,即班級的界面不應該改變。您想臨時更改界面,作爲黑客(儘管只有通過某些未公開的朋友功能的界面)。如果這是合理的,那麼更改班級正文是有道理的。如果沒有正當理由,那麼千萬不要計劃進行臨時黑客攻擊:正確地修復它... – 2010-09-23 17:35:29

回答

-1

處理這種情況的想法是一樣的功能添加:

void Ioctl(int func, void* params);上您的課。這個功能可以被用作所有這些hackey臨時場景的網關。當需求消失而不破壞兼容性時,它們可以安全地移除(除非有人非正式使用它們)。

確實,您確實失去了安全類型,但它確實爲所有這些問題提供了一種很好的瑞士軍刀方法。

在內部,您可以定義某些整數func值來調用函數,並將params值轉換爲任何您需要的值。

+1

除了丟失類型安全之外,這與添加方法有什麼不同?你只是自己重新實現了方法機制。就像你自己提到的那樣,你仍然依賴於用戶不使用這些功能。 – 2010-12-14 12:42:16

0

公共嵌套類做什麼工作呢?然後它可以有一個MapIndex1函數,該函數可以自動獲得對其封閉類的私有成員的訪問。完成後,只需刪除嵌套的類。

class Foo { 
// ... 
public: 
    void Insert(std::size_t index0, int index1, double d); 
    // ... other essential functions 
    class Remapper 
    { 
    public: 
    Remapper(Foo& foo) : foo_(foo) { } 
    void MapIndex1(const std::map<std::size_t,std::size_t>& old_to_new); 
    private: 
    Foo& foo_; 
    }; 
}; 

Foo myFoo; 
Foo::Remapper remapper(myFoo); 
remapper.MapIndex1(...); 
+0

我會將複製構造函數和'Foo :: Remapper'的複製賦值私有化,以減少濫用的可能性。 – aschepler 2011-02-03 03:19:04