2011-08-05 26 views
14

Tengo una clase de contenedor que está templada. Estoy sobrecargando el operador de asignación de modo que también se pueden asignar tipos derivados.Acceso a variables de miembros privados desde un operador de asignación de clase con plantilla

Mi problema es que, cuando el tipo no es el mismo, no puedo acceder a los miembros privados de la clase contenedora. ¿Cuál es el mejor enfoque para obtener acceso? Las variables miembro no pueden ser accesibles a través de captadores públicos. ¡Gracias!

Código Ejemplo:

// Note: var is private 

template <class T> 
Container<T>& Container<T>::operator=(const Container<T>& rhs) { 
    if(*this != rhs) var = rhs.var; // works for same type 
    return *this; 
} 

template <class T> 
template <typename U> 
Container<T>& Container<T>::operator=(const Container<U>& rhs) { 
    if(*this != rhs) var = rhs.var; // does NOT work for different types 
    return *this; 
} 
+2

Tienes que hacerles amigos, mira http: // stackoverflow.com/questions/3292795/template-friend – imre

+3

Su comprobación de igualdad parece ineficaz. Normalmente deberías verificar 'this! = & Rhs'. Mejor aún, use la expresión copiar y cambiar para implementar la asignación. –

+0

Es solo un código de ejemplo. De hecho, la clase contenedor funciona como un puntero inteligente, por lo tanto, el control es más simple. – steveo225

Respuesta

17

Desde desea acceder a miembros privados de clase de plantilla instancia con diferentes tipos, usted tiene que hacer otras plantillas como amigo de la clase de plantilla como:

template <class T> 
class Container 
{ 
     template<class U> 
     friend class Container; 

}; 

Tenga en cuenta que si T y U son tipos diferentes, entonces Container<T> y Container<U> son dos clases completamente diferentes; uno no puede acceder a miembros privados de otro si no haces amigo uno de otro.

También tenga en cuenta que en el código por encima de todas las instanciaciones de la plantilla de clase son amigo del entre sí. Es decir, si se ejemplariza con char, int, short, entonces

  • Container<int> va a ser amigo de ambos Container<char> y Container<short>.
  • Container<char> será amigo de ambos Container<int> y Container<short>.
  • Container<short> será amigo de ambos Container<int> y Container<char>.

La frase interesante aquí es: "amigo del otro". Por lo general, esto no sucede. Por ejemplo, si usted tiene una clase como esta:

class A 
{ 
    friend class B; 
}; 

Entonces aquí solamente B es amigo A. A NO es amigo de B. NO son "amigo uno del otro". B puede acceder a miembros privados de A, pero A no puede acceder a miembros privados de B. Esa es la diferencia entre esta clase y la clase de plantilla anterior.

+1

Gracias. Pensé que se necesitaba 'amigo', pero al parecer nunca usé la sintaxis correcta. – steveo225

1

El primer operador funciona porque el acceso es de clase y no de objeto. Eso significa que puede acceder a miembros privados en instancias de la misma clase.

Para acceder a un miembro privado de una clase diferente sin usar getters o setters, necesita hacer amigos de su clase con la otra clase.

Otras formas implican hacks, accediendo directamente a la memoria y no son portátiles.

Cuestiones relacionadas