2010-07-19 7 views
8

Duplicar posible:
clean C++ granular friend equivalent? (Answer: Attorney-Client Idiom)En C++, dada una función de miembro en la clase A, ¿podemos restringir su acceso a solo la clase B, sin darle a B el acceso de amigo completo a A?

He querido esto un par de veces y no han sido capaces de llegar a una buena manera de hacerlo.

Digamos que tengo una función miembro en la clase A. Deseo poder llamar a esa función desde una clase B no relacionada, pero no ser generalmente invocable. Podrías decir: "Claro, haz que la función sea privada y declara que B es amigo de A." Eso es lo que he estado haciendo, pero parece un poco exagerado. Realmente no quiero darle acceso a B a todo en A, solo una función.

En resumen: A::func() solo se puede llamar por la clase B, pero B no se ha declarado amigo de A. ¿Posible?

+2

Posible duplicado: http://stackoverflow.com/questions/3217390/clean-c-granular-friend-equivalent-answer-attorney-client-idiom –

+0

Mi pregunta es de hecho una duplicado de ese. Aparentemente mi búsqueda-foo es débil. –

Respuesta

5

Puede dividir la interfaz de A en varias clases base abstractas puras y luego dar a B una referencia a la interfaz que tiene el método apropiado. Otras clases solo obtendrían interfaces que no contienen este método. Tenga en cuenta que esto no es muy escalable, ya que la cantidad de interfaces puede ser muy grande rápidamente.

5

Una posible forma podría ser crear una clase confiable que envuelva A::func y pase un objeto contenedor a B. De nuevo, esto requiere que el contenedor sea amigo de A, pero solo necesita administrar una de esas clases, mientras que todas las clases externas pueden usar el contenedor.

Ejemplo:

class Wrapper; 

class A { 
    private: 
    void func(); 
    /* other methods */ 

    public: 
    Wrapper getWrapper(); 

    friend class Wrapper; 
}; 

class Wrapper { 
    private: 
    A &ref; 

    private: 
    Wrapper(A &obj) : ref(obj) { } 

    public: 
    void func() { 
     ref.func(); 
    } 

    friend class A; 
}; 

Wrapper A::getWrapper() { 
    return Wrapper(*this); 
} 
+0

Esta es una solución muy pesada, especialmente si necesita hacerlo en varios lugares. Además, no creo que las plantillas C++ le den ninguna forma de generalizar esto sobre diferentes funciones y nombres de clase (aunque podría estar equivocado), lo que significa que lo repetirá para cada función y clase de la tupla que quiera habilitar. . –

Cuestiones relacionadas