Allocazione di un oggetto in una variabile superclasse

di il
6 risposte

Allocazione di un oggetto in una variabile superclasse

So che il titolo è orribile ma non sapevo come riassumere meglio il mio problema:

In Java è possibile allocare memoria per un oggetto di una determinata classe ed assegnare a tale variabile un oggetto che sia una sottoclasse della classe suddetta.

Per esempio:
public class Figura
{...} //Superclasse
public class Triangolo extends Figura
{...} //Sottoclasse
public class Rettangolo extends Figura
{...} //Sottoclasse
public static void main(...)
{
   Figura array[2];
   Rettangolo r = new Rettangolo();
   Triangolo t = new Triangolo();

   Figura[0] = r;
   Figura[1] = t;
}
Ed è legittimo.

La mia domanda è se sia possibile fare una cosa del genere anche in C++, poiché né con gli array, né con le liste sembra fattibile. L'unica cosa che sono riuscito a fare è passare un reference Figura (Figura& f) ad una funzione in modo che riconoscesse di quale tipo di oggetto si tratta e chiamasse le funzioni di conseguenza.

Grazie a tutti

6 Risposte

  • Re: Allocazione di un oggetto in una variabile superclasse

    Si è possibile: anzi è la base del polimorfismo in C++.
    Attenzione però che, a differenza di Java, il C++ non ha un garbage collector per cui devi rilasciare esplicitamente la memoria. O usare degli smart pointer che ci pensino al posto tuo. Detto questo quel codice si traduce come:
    
    class Figura {
        ...
    };
    
    class Triangolo : public Figura {
    };
    
    class Rettangolo : public Figura {
    };
    
    int main() {
       Figura* figure[2];
       Rettangolo* r = new Rettangolo();
       Triangolo* t = new Triangolo();
    
       figure[0] = r;
       figure[1] = t;
    
       delete r;
       delete t;
    }
    
    Attualmente però è meglio fare:
    
    
       std::shared_ptr<Figura> figure[2];
       figure[0] = new Rettangolo();
       figure[1] = new Triangolo();
    
    
    e lasciare che sia lo shared_ptr a occuparsi della gestione della memoria.
  • Re: Allocazione di un oggetto in una variabile superclasse

    Grazie infinite, non sapevo del new() come funzione, io inizializzavo usando le graffe
  • Re: Allocazione di un oggetto in una variabile superclasse

    In realtà è un operatore.
    Il fatto che ci siano le () finali è solo perché ho fatto un copia, modifica incolla.
    Funziona lo stesso anche senza.
  • Re: Allocazione di un oggetto in una variabile superclasse

    Altri problemi

    Ho provato a fare come mi hai detto tu:
    std::shared_ptr<Shape> prova;
    prova = new Rectangle();
    ma mi vengono restituiti questi errori:
    '=' binario: non è stato trovato alcun operatore che accetti un operando destro di tipo 'Rectangle *'. È anche possibile che non vi siano conversioni accettabili.
    IntelliSense: nessun operatore "=" corrispondente agli operandi. 
    I tipi di operando sono: std::shared_ptr<Shape> = Rectangle *
    Ma il "new" non dovrebbe già restituire un puntatore?

    Altra cosa è che se io scrivo
    std::shared_ptr<Shape> prova {new Rectangle()};
    Il compilatore non da problemi, ma a run-time succede questo:
    'cast di tipo': conversione da 'Rectangle *' a 'Shape *' esistente ma inaccessibile
    Premetto che Shape contene un metodo virtuale puro, potrebbe essere quello che da problemi? In tal caso come devo implementare il tutto per farlo funzionare?

    Il mio intento è fare una cosa del genere:
    std::list<std::shared_ptr<Shape>> lista;
    e poter gestire dinamicamente gli oggetti nel programma.
  • Re: Allocazione di un oggetto in una variabile superclasse

    http://en.cppreference.com/w/cpp/memory/shared_pt
    qui c'è la documentazione dello shared_ptr.
    Se noti non c'è un metodo operator=() che prende un puntatore come quello restituito dalla new (raw pointer)
    Il metodo che devi usare è reset();
    
    std::shared_ptr<Shape> prova;
    prova.reset(new Rectangle());
    prova->metodo() etc...
    
    ma a run-time succede questo: ...
    Devi dichiarare public i costruttori delle classi.
    
    class Rettangolo : public Shape {
    
        public:
            Rettangolo() etc...
    };
    
  • Re: Allocazione di un oggetto in una variabile superclasse

    Ce l'ho fatta dopo varie ricerche, ma grazie comunque

    Però invece di reset() ho usato make_shared() e funziona lo stesso, sono anche riuscito ad implementare la lista come volevo.
Devi accedere o registrarti per scrivere nel forum
6 risposte