Il primo punto e' il metodo set della classe Interfaccia: dato che passo un puntatore che per i piu' disparati motivi potrebbe non essere quello atteso dal dato membro mBase, e dato che il senso del metodo e' quello di settare i dati che gli passo, mi sembra fuorviante o comunque poco consistente permettere che venga cambiato il tipo di mBase secondo il tipo di Struct che gli passo. Se ho creato un oggetto di un certo tipo e gli passo una struttura dati di un tipo diverso, col solo metodo set implementato non riesco a capire se cambio il tipo di mBase per errore mio o perche' lo voglio veramente
Il pattern strategy funziona così. Costruisci un oggetto in un modo, poi puoi cambiarlo a piacimento tramite un parametro e una funzione. Se i dati che passi in Interfaccia::set() si riferiscono a una classe derivata e non a quella attualmente in essere dentro mBase, cambi l'oggetto dentro mBase. Se invece i dati si riferiscono all'oggetto dentro mBase aggiorni l'oggetto.
Non è ne fuorviante ne poco consistente.

Altra cosa se mBase non e' ancora stato inizializzato o per qualsiasi motivo e' diventato nullptr: anche in questo caso, nella logica per cui viene implementato il metodo set, cioe' settare i dati membro di un oggetto, se mBase e' nullptr lo inizializzo col metodo set, o meglio sollevare un'eccezione?
se mBase è nullptr non puoi proprio usarlo per accedere ai metodi, pertanto il problema non si pone nemmeno.
Eccezione? Non serve. Se mBase è nullptr lo crei e lo imposti con i dati che ti servono. Altrimenti hai questo:
codice:
Interfaccia ai(nullptr);
ai.set(puntatore valido) // bang!!!
Non mi pare abbia senso.

Per il metodo getType: se mBase e' nullptr, cosa ha piu' senso, eccezione o restituisco comunque un valore che indica che mBase in realta' e' nullptr?
Stessa cosa per get: se mBase e' nullptr, che si fa di solito, restituisco un nullptr, indice della situazione anomala, o eccezione?

Mi rendo conto che sono scelte personali, che una volta fatte e messe nei commenti al codice, sia una che l'altra strada possono essere valide, pero' vorrei sapere cosa si tende a fare in genere in queste situazioni.
Bella domanda! C'è chi non userebbe le eccezioni nemmeno sotto tortura e chi ci condirebbe pure l'insalata.
Posso dirti come mi regolo io, ossia usare le eccezioni se è violato un prerequisito oppure se non so che fare.
Stroustroup una volta ha detto che sono solo due le eccezioni problematiche: una bad_cast in caso di dynamic_cast fallito e la bad_alloc se non c'è più memoria. Il resto degli errori sono controllabili, se qualcuno li controlla.
C'è questo bell'articolo sul tema
https://www.codeproject.com/articles...-pros-and-cons

Ad esempio il fatto che mBase non possa essere nullptr è un prerequisito?
Se si allora ogni volta che mBase è nullptr lancio l'eccezione, altrimenti gestisco la cosa tramite qualche if.
Il parametro data != nullptr è un prerequisito? Come sopra.

Questa mi incuriosisce, chiedo troppo se chiedo "come la semplificheresti?"
Ho semplicemente pensato che all'interno dei case dello switch potresti scrivere direttamente il codice delle makeDerivedX dal momento che gli passi il parametro data, ma probabilmente è più pulito così com'è.