Dopo aver fatto alcune ricerche, non riesco a trovare un semplice esempio per risolvere un problema che ho riscontrato spesso.
 Diciamo che voglio creare una piccola applicazione in cui posso creare   Square    s,   Circle    s e altre forme, visualizzarle su uno schermo, modificare le loro proprietà dopo averle selezionate, e quindi calcolare tutti i loro perimetri . 
Vorrei fare la classe modello in questo modo:
class AbstractShape
{
public :
    typedef enum{
        SQUARE = 0,
        CIRCLE,
    } SHAPE_TYPE;
    AbstractShape(SHAPE_TYPE type):m_type(type){}
    virtual ~AbstractShape();
    virtual float computePerimeter() const = 0;
    SHAPE_TYPE getType() const{return m_type;}
protected :
    const SHAPE_TYPE  m_type;
};
class Square : public AbstractShape
{
public:
    Square():AbstractShape(SQUARE){}
    ~Square();
    void setWidth(float w){m_width = w;}
    float getWidth() const{return m_width;}
    float computePerimeter() const{
        return m_width*4;
    }
private :
    float m_width;
};
class Circle : public AbstractShape
{
public:
    Circle():AbstractShape(CIRCLE){}
    ~Circle();
    void setRadius(float w){m_radius = w;}
    float getRadius() const{return m_radius;}
    float computePerimeter() const{
        return 2*M_PI*m_radius;
    }
private :
    float m_radius;
};
(Immaginiamo di avere più classi di forme: triangoli, esagoni, con ogni volta le loro variabili proprers e getter e setter associati.I problemi che ho affrontato hanno avuto 8 sottoclassi ma per amore dell'esempio mi sono fermato a 2)
 Ora ho   ShapeManager   , istanziando e memorizzando tutte le forme in un array: 
class ShapeManager
{
public:
    ShapeManager();
    ~ShapeManager();
    void addShape(AbstractShape* shape){
        m_shapes.push_back(shape);
    }
    float computeShapePerimeter(int shapeIndex){
        return m_shapes[shapeIndex]->computePerimeter();
    }
private :
    std::vector<AbstractShape*> m_shapes;
};
 Infine, ho una vista con le caselle di selezione per cambiare ogni parametro per ogni tipo di forma. Ad esempio, quando seleziono un quadrato sullo schermo, il widget dei parametri mostra solo i parametri relativi a   Square    (grazie a   AbstractShape::getType()   ) e propone di modificare la larghezza del quadrato.
Per farlo ho bisogno di una funzione che mi permetta di modificare la larghezza in   ShapeManager   , e questo è il modo in cui lo faccio: 
void ShapeManager::changeSquareWidth(int shapeIndex, float width){
   Square* square = dynamic_cast<Square*>(m_shapes[shapeIndex]);
   assert(square);
   square->setWidth(width);
}
 C'è un design migliore che mi eviti di usare   dynamic_cast    e di implementare una coppia getter / setter in   ShapeManager    per ogni variabile sottoclasse che posso avere? Ho già provato a utilizzare  modello ma non sono riuscito . 
 Il problema che sto affrontando non è in realtà con le forme ma con  diverso   Job    s  per una stampante 3D (es:   PrintPatternInZoneJob   ,   TakePhotoOfZone   , ecc.) con   AbstractJob    come loro classe base. Il metodo virtuale è   execute()    e non   getPerimeter()   .  L'unica volta che ho bisogno di utilizzare l'utilizzo concreto è di riempire le informazioni specifiche richieste da un lavoro : 
-  PrintPatternInZonerichiede l'elenco di punti da stampare, la posizione della zona, alcuni parametri di stampa come la temperatura
-  TakePhotoOfZoneha bisogno di quale zona prendere in foto, il percorso in cui verrà salvata la foto, le dimensioni, ecc ...
 Quando chiamerò   execute()   , i lavori useranno le informazioni specifiche che hanno per realizzare l'azione che dovrebbero fare. 
  L'unica volta che ho bisogno di usare il tipo concreto di un lavoro è quando compilo o visualizzo queste informazioni  (se è selezionato un   TakePhotoOfZone      Job   , un widget che mostra e modifica la zona verranno mostrati i parametri di percorso, e dimensioni). 
 I   Job    s vengono quindi inseriti in un elenco di   Job    s che prende il primo lavoro, lo esegue (chiamando   AbstractJob::execute()   ), passa al successivo, e fino alla fine dell'elenco . (Questo è il motivo per cui utilizzo l'ereditarietà). 
  Per memorizzare i diversi tipi di parametri  Uso un   JsonObject   : 
- 
Vantaggi 
-  : stessa struttura per qualsiasi lavoro, nessun dynamic_cast quando si impostano o si leggono i parametri 
-  problema: impossibile memorizzare puntatori (a PatternoZone)
Credi che ci sia un modo migliore per archiviare i dati?
 Quindi  come vorresti memorizzare il tipo concreto di   Job     per usarlo quando devo modificare i parametri specifici di quel tipo?    JobManager    ha solo un elenco di   AbstractJob*   .