2009-10-22 9 views
12

Quiero hacer una clase Una clase de amigo de clase B. Quiero hacer esto ya que estos interactúan mucho y A necesita cambiar las partes internas de la clase B (que no quiero exponer con el público) . Pero quiero asegurarme de que solo tiene acceso a algunas funciones seleccionadas, no a todas las funciones.clase de amigo con acceso limitado

Ejemplo:

class A 
{ 
}; 

class B 
{ 
private: 
void setState(); 
void setFlags(); 
friend class A 
}; 

Quiero A a acceder a setstate pero no setFlags ... ¿Existe un patrón de diseño o una buena manera de hacer esto ¿o me quedo con acceso completo o nada acceso en absoluto en este caso.

Gracias

+0

Aparte del hecho de que puedes personalizar tu cuenta (hay tantos desconocidos ...), esa es una pregunta muy interesante. ¡Todavía estoy jugando con la clave y la interfaz privada en este momento! –

Respuesta

26

depende de lo que entendemos por "un buen camino" :) En comp.lang.C++. Moderó tuvimos la misma pregunta hace un tiempo. Puede ver la discusión que generó there.

IIRC, terminamos utilizando el enfoque de "amigo de una clave anidada". Aplicado a su ejemplo, esto dió:

class A 
{ 
}; 

class B 
{ 
public: 
    class Key{ 
     friend class A; 
     Key(); 
    }; 

    void setFlags(Key){setFlags();}   

private: 
    void setState(); 
    void setFlags(); 
}; 

La idea es que los setFlags públicas deben ser llamados() con una "llave", y sólo los amigos de clave puede crear uno, como su ctor es privada.

+0

+1: No he visto esto antes, realmente muy inteligente. –

+0

Realmente inteligente. Usualmente dependía de un 'contrato' ya que no había peleado de ninguna manera con esto ... ¡aprendes todos los días! –

+0

Por cierto, en la pregunta de OP, quería acceder a setState, no a setFlags ... sí, soy pedante ... –

7

Un enfoque es a través de interfaces explícitas, ya que el implementador de una interfaz puede seleccionar que les dan a:

class NearlyPrivateInterface { 
public: 
    virtual void setState() = 0; 
    virtual void setFlags() = 0; 
}; 

class A { 
public: 
    void attach(NearlyPrivateInterface* instanceOfB); 
}; 

class B: private NearlyPrivateInterface { 
public: 
    void attach(A& a) { a.attach(this); } 
}; 
+1

Que el patrón de interfaz privada: http://www.objectmentor.com/resources/articles/privateInterface.pdf –

2

Usted puede hacer lo siguiente ..

class A{ 
}; 

class B{ 
private: 
    void setFlags(); 
protected: 
    void setState(); 

}; 

class RestrictedB :public B{ 
    friend class A; 
}; 
Cuestiones relacionadas