2016-04-13 55 views
1

için yazılabilir çok sayıda salt okunur Bazı sınıflarda gruplanmış büyük miktarlarda dizelerim var, hepsi son bir dev sınıfta gruplandırılmış. Bu sınıf başka bir sınıf tarafından doldurulmalı ve değişmez içeriği bazı istemciler tarafından karşılanmalıdır. (Elbette, bu sınıflar bu basitleştirilmiş şematik temsilidir, daha karmaşıktır.)Farklı erişimli sınıf: ayrıcalıklı

Çözüm 1:

class A 
{ 
friend class M; 

private: 
    B m_b; 
    C m_c; 
    D m_d; 

public: 
    const B& GetB() const { return m_b;} 
    const C& GetC() const { return m_C;} 
    const D& GetD() const { return m_D;} 

private: 
    B& GetB() { return m_b;} 
    C& GetC() { return m_C;} 
    D& GetD() { return m_D;} 
} 

nerede B gibi bir şey:

class B 
{ 
friend class M; 

private: 
    std::string m_camel; 
    std::string m_pink; 
    std::string m_vandergraaf; 

public: 
    const std::string& Camel() const { return m_camel;} 
    const std::string& PinkFloyd() const { return m_pink;} 
    const std::string& VanDerGraafGenerator() const { return m_vandergraaf;} 

private: 
    void SetCamel(const char* prog) { m_camel = prog;} 
    void SetPinkFloyd(const char* prog) { m_pink = prog;} 
    void SetVanDerGraafGenerator(const char* prog) { m_vandergraaf = prog;} 
} 

Daha iyi bir çözüm, yani protected için friend'un önlenmesi, yazma erişim sınıfını M'ye ve üssü olan, yalnızca dünyaya açık bir şekilde göstermektir.

Çözüm 2: B için

class A 
{ 
protected: 
    B m_b; 
    C m_c; 
    D m_d; 

public: 
    const B& GetB() const { return m_b;} 
    const C& GetC() const { return m_C;} 
    const D& GetD() const { return m_D;} 
} 

// only visible to M 
class A_Write: public A 
{ 
public: 
    B& GetB() { return m_b;} 
    C& GetC() { return m_C;} 
    D& GetD() { return m_D;} 
} 

Aynı şey belki. Müşteriler kendi sınıflarını da türetebildikleri için çok iyi bir çözüm değil.

daha iyi, ancak daha kısıtlama varyant çözeltisi 3'dür:

class A 
{ 
private: 
    const B m_b; 
    const C m_c; 
    const D m_d; 

public: 
    const B& GetB() const { return m_b;} 
    const C& GetC() const { return m_C;} 
    const D& GetD() const { return m_D;} 

protected: 
    A(const B& b, const C& c, const D& d): m_b(), m_c(c), m_d(d) {} 
} 

// only visible to M 
class A_Write: public A 
{ 
public: 
    A_Write(const B& b, const C& c, const D& d): A(b, c, d) {} 
} 

My tercih edilen çözüm ... olan 4 3 ancak B, C, D, daha basit struct s yerine class es. Yani M, B, C, D'de doğrudan istediği her şeyi yapabilir, sonra bir A_Write kurar.

Daha iyi bir fikir?

+0

. Hiç denedin mi? – skypjack

+0

Bunu mu demek istediniz: PIMPL? Bu bir: http://en.wikipedia.org/wiki/Proxy_pattern? Bazı sanal mı demek istiyorsun? İlk düşüncem bu benim durumum için çok ağır olurdu. Şimdilik yatmam lazım, bye! – Liviu

+0

Düşüncelerinizi bir cevapta dile getirebilir misiniz? Bazı sınıf şemasıyla mı? – Liviu

cevap

1

Muhtemel bir yaklaşım, sınıfınızın arayüzünü azaltan bir proxy kullanmak olabilir.
M sınıfı, S örneğini (arabirimini kullanarak değiştirebilmek için) başlatır/alır, ancak okuyucular için bir proxy P döndürür (değiştirmeyi başaramaz).
Bu minimal bir örnek aşağıdaki gibidir:

bir proxy bir arayüz görünürlüğünü azaltmak için, kullanılabilir ne
struct S { 
    void value(int v) noexcept { t = v; } 
    int value() const noexcept { return t; } 
private: 
    int t{0}; 
}; 

struct P { 
    P(S& s): b{s} { } 
    int value() const noexcept { return b.value(); } 
private: 
    S& b; 
}; 

int main() { 
    // the class: full interface 
    S s; 
    // the proxy: reduced interface 
    P p{s}; 
} 
+0

Çözümünüzü beğendim, ancak P'nin tüm üyeler için "proxy" işlevlerini (değer) yazmasını önlemek için bir const referansını S'ye (ve diğerlerine) döndürebileceğini düşünüyorum. – Liviu

+0

İkinci çözüm benim şirketim tarafından tercih edildi, çünkü sınıfları ayırdığı için sizinki daha iyi. – Liviu