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.

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top