Come sovrascrivere la funzione in una sottoclasse che ha funzionalità uniche nel mezzo della funzione rispetto al genitore

4

scusa se il titolo è un po 'confuso ma non ero sicuro di come formulare la mia domanda. Quindi ho alcune classi che ho usato per un progetto che sto cercando di rendere più generale in modo che io possa riutilizzarle per altri progetti. L'idea era di spostare tutto il codice che è univoco per il progetto corrente in una sottoclasse della classe originale. Ciò ha funzionato bene per la maggior parte delle parti poiché il modo più comune di eseguire una funzione era che il comportamento generale era il primo nella funzione e che il comportamento specifico del programma è durato. Quindi nella mia nuova soluzione chiamo semplicemente la funzione della classe base dalla sottoclasse e poi faccio il codice specifico del programma o viceversa. Ad esempio questo:

void ParentClass::doStuff()
{
    doGeneralStuff();
    doprogramSpecificStuff();
}

Diventerebbe questo:

void ParentClass::doStuff()
{
    doGeneralStuff();
}

void SubClass::doStuff()
{
    ParentClass::doStuff();
    doProgramSpecificStuff();
}

Il problema sorge quando ho una funzione simile a questa:

void ParentClass::doOtherStuff()
{
    doOtherGeneralStuff();
    if (condition) {
        doEvenMoreGeneralStuff();
        doMoreProgramSpecificStuff();
    }
    doTheLastGeneralStuff();
}

Ora il codice specifico del programma si trova nel mezzo della funzione. Un modo per risolverlo sarebbe semplicemente copiare l'intera funzione nella sottoclasse e rimuovere la linea specifica del programma dal genitore. Ma poi finirei con il codice pubblicizzato e se dovessi cambiare il comportamento del mio programma lungo la linea che potrebbe diventare un problema. Immagino che un altro modo per risolverlo sia chiamare una funzione della classe genitore che è vuota ma che può essere sovrascritta in una sottoclasse se desidera fare qualcosa in quel punto del programma. Ma anche questo sembra un po 'brutto finisco con un sacco di sottoclassi che hanno bisogno di fare cose del genere. Quindi finirei con un sacco di chiamate di funzioni appena vuote.

Qualche consiglio su come risolvere questo problema?

    
posta Jesper Evertsson 01.03.2017 - 12:25
fonte

2 risposte

4

La soluzione generale a questi problemi è data dal metodo modello modello di progettazione.

Usando questo modello, puoi aggiungere punti di estensione al tuo ParentClass dove le classi derivate possono "iniettare" il loro comportamento specifico, come questo:

class ParentClass
{
public:
  void DoSomething()
  {
    doSpecificPreStuff();

    // do some generic stuff

    doSpecificMiddleStuff();

    // do some generic stuff

    doSpecificPostStuff();
  }
protected:
  virtual void doSpecificPreStuff() {}
  virtual void doSpecificMiddleStuff() {}
  virtual void doSpecificPostStuff() {}
};

class SubClass {
private:
  void doSpecificMiddleStuff() {
    // Do specific stuff
  }
  // Steps where no specific behaviour is needed are not overridden
};
    
risposta data 01.03.2017 - 15:13
fonte
2

Sebbene la premessa sembri un codice olfattivo per me, puoi ottenere qualcosa di simile con il modello di modello curiosamente ricorrente (CRTP) . Permette alla classe base di dipendere dalla classe derivata e ha accesso ad alcune delle sue funzionalità.

template<class Derived>
class ParentClass
{
//...
}

class SubClass : public ParentClass<SubClass>
{
//...
} 

template<class Derived>
inline void ParentClass<Derived>::doOtherStuff()
{
    doOtherGeneralStuff();
    if (condition) {
        doEvenMoreGeneralStuff();
        static_cast<Derived*>(this)->doMoreProgramSpecificStuff();
    }
    doTheLastGeneralStuff();
}
    
risposta data 01.03.2017 - 12:57
fonte

Leggi altre domande sui tag