Domanda

Come implementare colata a una classe base privata in C ++? Non voglio usare hack come l'aggiunta di un amico ecc Definizione operatore di colata pubblica non funziona.

EDIT:

Per esempio io ho:

class A {
//base class
}

class AX : private A {
//a child
}

class AY : private A {
//another specialized child
}

class B {
//base class
void do (A a) {//do
    }
}

class BX : private B {
//a child
void do (AX a) {
     B::do( static_cast <A> (a) );
    }
}

class BY : private B {
//another specialized child
void do (AY a) {
    B::do( static_cast <A> (a) );
    }
}

EDIT2

Perché lo faccio?

Supponiamo che io ho per definire alcune proprietà che è abbastanza pesante e può essere di diversi tipi simili (come VelocityX VelocityY ecc). Allora io voglio essere in grado di avere le classi che possono avere qualsiasi insieme di queste proprietà. Se voglio elaborare queste proprietà, è ovvio, che io preferirei le precipitava loro tipo di base che per aggiungere un'implementazione per ogni variazione. Io non uso l'ereditarietà pubblica perché è meglio per il cast esplicito dove necessario che avere l'interfaccia privata implicitamente visibile. Non è un vero problema, ma mi piacerebbe avere una soluzione:)

È stato utile?

Soluzione

Se la definizione di un operatore di colata pubblica non funziona, si può provare con una normale funzione:

class D: private B {
    public:
        B& asB() { return static_cast<B&>(*this); }
};
...
D d;
d.asB().methodInB();
...

In ogni caso, qual è il punto? Se deriva D privatamente da B, allora non sono tenuti a utilizzare un D come B dall'esterno.

Altri suggerimenti

Si può semplicemente utilizzare un cast C-style. Non c'è bisogno di nessun "hack" o "implementazioni". Avvolgendolo in una funzione esplicita serve il "cast C-Style sono cattive" persone

template<typename Targ, typename Src>
typename boost::enable_if<boost::is_base_of<Targ, Src>, Targ>::type &
private_cast(Src &src) { return (Targ&)src; }

Per avere la cassaforte cast, è necessario assicurarsi che Targ è in realtà una base privata o pubblica. Questo viene fatto boost::is_base_of.


Naturalmente si dovrebbe preferire funzioni membro nella rispettiva classe derivata che restituisce il puntatore base, invece di fare un cast. .


  

La definizione di operatore di colata pubblico non funziona.

Che non ha senso per me ... Perché fare la classe base privata a tutti allora? Basta renderlo pubblico. Il motivo per cui le funzioni di conversione non funzionano è perché il Principio richiede che le conversioni implicite non considerano mai le funzioni di conversione per una classe base, la classe stessa o void.

Ho un caso d'uso per questo; Sto eredita da una grande e volatile classe di base che è l'aggiunta di funzioni di tutto il tempo e quasi mai è la funzione di classe di base di andare a lavorare correttamente nel mio sottoclasse, così ho ereditato in privato.

Credo che sia più semplice solo per fare una funzione che restituisce classe di base. Qui di seguito elencare un programma completamente corretta; Si prega di provare a compilare il codice prima di presentare una domanda, dal momento che utilizzando identificatori come "fare", come i nomi delle funzioni rischia di rendere ogni compilatore infelice .. :-(: - (

class A {
  //base class                                                                                                                                                          
};

class AX : private A {
  //a child                                                                                                                                                             
 public:
  A *ToA() { return this; }
};

class AY : private A {
  //another specialized child                                                                                                                                           
 public:
  A *ToA() { return this; }
};

class B {
  //base class                                                                                                                                                          
 protected:
  void do_it (A a) {};
};

class BX : private B {
  //a child                                                                                                                                                             
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

class BY : private B {
  //another specialized child                                                                                                                                           
  void do_it (AX a) {
    B::do_it( *a.ToA() );
  }
};

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top