2011-01-12 13 views
9

Estoy usando herencia privada en un proyecto, en el sentido "implementado en términos de". La clase base define operator [], y esta es la funcionalidad que quiero usar. Por lo tanto, tengoHerencia privada usando directivas, sobrecargas?

class A : private B { 
    using B::operator[]; 
    // ... 
}; 

Sin embargo, ¿cómo puedo controlar qué versión del operador [] obtengo? De hecho, necesito más de una, tanto las versiones const y no const. ¿Se puede lograr esto?

+3

En este caso, podría usar la composición para darle el resultado deseado en lugar de la herencia privada. – James

+1

Sí, lo sé ... lo cambié a herencia privada para reducir la cantidad de código de reenvío. Entonces no es posible? ¿Cómo se elige la función de forma adecuada? – carlpett

+0

Su código será mucho más fácil de escribir y mantener si utiliza la composición en lugar de la herencia privada aquí. La regla empírica es no utilizar las características extravagantes de C++ cuando no son absolutamente necesarias (por lo que ha dicho hasta ahora, la herencia privada no es necesaria en este caso). –

Respuesta

6

Tengo entendido que su using debe traer automáticamente todas las diferentes sobrecargas del operador. ¿Hay ciertas sobrecargas que desea excluir de ser llevadas a la clase infantil? En ese caso, podría ser mejor dividir el trabajo en varias funciones con nombre diferente en el elemento primario y solo las using que necesite.

+0

Yo también lo hubiera pensado, pero recibo errores de compilación por descarte, a pesar de que hay versiones que devuelven 'T &' y 'const T &' (template typename T) – carlpett

+0

Entonces, este es uno de ellos "mágicamente arreglado "veces ... Después de buscar el código y volver a compilarlo, de repente funciona, y no puedo entender lo que cambié. Sin embargo, lo que sí cambió es que aprendí un poco más sobre la herencia, ¡así que gracias! – carlpett

2

Esto hace como se esperaba:

class A 
{ 
public: 
    int operator[](int idx) { return 0; } 
    int operator[](int idx) const { return 1; } 
}; 

class B : public A 
{ 
public: 
    using A::operator[]; 

    void opa() { cout << operator[](1) << endl; } 
    void opb() const { cout << operator[](1) << endl; } 
}; 

int main(void) 
{ 
    B b; 
    b.opa(); 
    b.opb(); 

    const B d = B(); 
    cout << d[1] << endl; // should trigger the const version of operator[] 
    return 0; 
} 

En otras palabras, las versiones const const apropiado/no se inyectan en B. NOTA: Si no se proporciona la versión de const, entonces recibirá un error de compilación (esto funciona si la herencia es privada o pública).

+0

¡Gracias, buen ejemplo! – carlpett

+0

También agregaría 'b [2];' o similar a 'main' para mostrar que las funciones del operador se pueden usar directamente desde fuera de' clase B'. – aschepler

+0

@aschepler, buen punto, se actualizará ... – Nim