Redux de lanzamientos automáticos
Pregunta
después de que yo estropeó la descripción de mi publicación anterior Sobre esto me senté y traté de transmitir mi intención exacta.
Tengo una clase llamada P que realiza algún propósito distinto.También tengo PW que realiza algún propósito distinto en P.PW no tiene variables miembro, solo funciones miembro.
A partir de esta descripción, asumirías que el código sería así:
class P
{
public:
void a( );
};
class PW
{
public:
PW( const P& p ) : p( p ) { }
void b( );
P& p;
};
class C
{
public:
P GetP( ) const { return p; }
private:
P p;
};
// ...
PW& p = c.GetP( ); // valid
// ...
Sin embargo, eso plantea un problema.No puedo llamar a las funciones de P sin dirección indirecta en todas partes.
// ...
p->p->a( )
// ...
Lo que me gustaría hacer es llamar a p->a() y hacer que determine automáticamente que me gustaría llamar a la función miembro de P.
También tener un miembro de PW llamado a realmente no escala; ¿qué pasa si agrego (o elimino) otra función a P? Será necesario agregarla (o eliminarla) a PW.
Solución
Puede intentar anular operador* y operador-> para devolver el acceso a la p incrustada.Algo como esto podría funcionar:
class P
{
public:
void a( ) { std::cout << "a" << std::endl; }
};
class PW
{
public:
PW(P& p) : p(p) { }
void b( ) { std::cout << "b" << std::endl; }
P & operator*() { return p; }
P * operator->() { return &p; }
private:
P & p;
};
class C
{
public:
P & getP() { return p; }
private:
P p;
};
int main()
{
C c;
PW pw(c.getP());
(*pw).a();
pw->a();
pw.b();
return EXIT_SUCCESS;
}
Este código se imprime
a
a
b
Sin embargo, este método puede confundir al usuario ya que la semántica de operador* y operador-> se confunde un poco.
Otros consejos
Si convierte a P en una superclase de PW, como lo hizo en su pregunta anterior, podría llamar a p->a() y lo dirigiría a la clase P.Sin embargo, parece que ya lo has considerado y rechazado, a juzgar por esta pregunta.Si es así, ¿le importaría explicarnos por qué esto no funciona para usted?
Creo que es necesario pensar qué tipo de relación existe entre PW y P.
¿Es una relación es-un?¿Las instancias de PW son instancias de P?Entonces tendría sentido que PW herede de P.
¿Es una relación de "tiene-a"?Entonces deberías limitarte a la contención y soportar los inconvenientes sintácticos.
Por cierto, generalmente no es una buena idea exponer una referencia no constante a una variable miembro en la interfaz pública de una clase.