簡體   English   中英

組合類C ++中的封裝

[英]Encapsulation in a Composition Class C++

我有一個地圖類,其中包含一個包含MapEntitys的向量。 MapEntity是繼承自Factory,Farm和其他3個類的類。

這5個類都應每隔幾秒鍾被“滴答”一聲,這時它們都將對每個類單獨執行一個功能,但是只有map類才能“勾號”它們。

我如何在C ++中支持這種類型的封裝? 朋友? 我應該只使用公共方法而不濫用這些方法嗎? (盡管為了更好的實踐,我更喜歡適當的封裝,即使不會重新分發此代碼)。

從語法上講,您可以使用任何一種。

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

是的,公共方法是正確的封裝。 他們告訴班級的用戶它可以做什么。 在這種情況下,用戶是Map類,並且可以在MapEntities上tick

僅當MapEntities 設計為僅由Map使用時,才應考慮其他解決方案(朋友,匿名名稱空間等)。

您可以使用friend ,但我認為最好不要對可以“勾選” MapEntity類的內容施加任何限制。

將人為的限制放入代碼中通常被認為是不好的做法。 即使您只希望地圖類現在能夠調用此函數,但將來可能會改變。

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

我認為您的任務類似於設計模式的訪客描述。

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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM