2011-03-05 55 views
0

不知道標題的措辭是否正確,但這裏寫着:組合類中的封裝C++

我有一個map類,它包含一個包含MapEntitys的向量。 MapEntity是Factory,Farm和其他三個類繼承的類。

這5個類都應該每隔幾秒鐘「打勾」一次,在這一點上它們都會爲每個類做一個單獨的功能,但只有地圖類應該能夠「勾選」它們。

我該如何在C++中支持這種類型的封裝?朋友?我應該使用公共方法而不是濫用這些方法嗎? (雖然我寧願適當的封裝以便於良好的實踐,但即使此代碼不會被重新分配)

同樣,我意識到這不是很好,所以請裸露在我身邊。在此先感謝,埃爾。

回答

2

句法上你可以使用任何一種。

但是,如果要從外部「勾選」MapEntities,則方法tick應該是其公共方法的一部分。實際上,它應該是虛擬的MapEntity類的公共方法。

是的,公共方法是適當的封裝。他們告訴你的班級的用戶它可以做什麼。在這種情況下,用戶是Map類,它可以是tick MapEntities。

你應該考慮其他的解決方案(朋友,匿名命名空間等),只有當MapEntities設計要由Map僅使用。

+0

感謝信息:d。我將使用虛擬公共方法 – Ell 2011-03-05 22:09:09

2

您可以使用friend,但我認爲最好不要對可勾選MapEntity類的內容進行限制。

在您的代碼中添加人爲限制通常被認爲是不好的做法。即使你只想讓你的地圖類能夠立即調用這個函數,這在未來可能會改變。

+0

感謝你們,我認爲限制代碼是正確的做法:s – Ell 2011-03-05 22:10:26

+0

不,使用封裝的原因是保護數據,而不是限制代碼。當你想保護數據時通常使用封裝,通常是爲了強制數據改變的副作用。 – 2011-03-06 00:03:50

0

使用friend實際上會降低封裝的程度,因爲您的地圖類將看到MapEntities的任何私有,而不僅僅是tick方法。

0

在我看來你的任務看起來像設計模式訪客描述。

class Visitor; 

class MapEntity 
{ 
    public: 
    virtual void tick(Visitor &v) = 0; 
}; 

class Factory: public MapEntity 
{ 
    public: 
    void accept(Visitor &v); 
    // ... 
}; 

class Farm: public MapEntity 
{ 
    public: 
    void tick(Visitor &v); 
    // ... 
}; 

class Mill: public MapEntity 
{ 
    public: 
    void tick(Visitor &v); 
    // ... 
}; 

class Visitor 
{ 
    public: 
    virtual void visit(Factory *e) = 0; 
    virtual void visit(Farm *e) = 0; 
    virtual void visit(Mill *e) = 0; 
}; 

void Factory::tick(Visitor &v) { v.visit(this); } 
void Farm::tick(Visitor &v) { v.visit(this); } 
void Mill::tick(Visitor &v) { v.visit(this); } 

class SomeVisitor: public Visitor 
{ 
    void visit(Factory *e) { /* ... */ }; 
    void visit(Farm *e) { /* ... */ }; 
    void visit(Mill *e) { /* ... */ }; 
}; 

class OtherVisitor: public Visitor { /* ... */ }; 

客戶端代碼:

MapEntity *enities[]; 
// ... 
SomeVisitor v1; 
OtherVisitor v2; 
for (int i = 0; i < N; ++i) 
{ 
    entities[i].tick(v1); 
} 
for (int i = 0; i < N; ++i) 
{ 
    entities[i].tick(v2); 
}