Se parli di variabili di tipi polimorfici definiti dall'utente, in C ++ devi usare un puntatore o un riferimento per ottenere il polimorfismo di runtime. La sintassi esatta che stai descrivendo è probabilmente legale in C ++ (difficile da dire dato che non hai fornito un esempio completo), ma si traduce in "slicing degli oggetti" piuttosto che polimorfismo.
Il motivo è che una variabile non puntatore / non di riferimento in C ++ indica sempre un oggetto che è archiviato nello stack e ha una struttura nota in fase di compilazione (sebbene quella struttura nota possa includere puntatori a roba sconosciuta ). L'unico modo per compilare il codice usando oggetti con una struttura sconosciuta è usare puntatori o riferimenti a quegli oggetti, poiché la struttura di un puntatore o di un riferimento è la stessa e nota al momento della compilazione, indipendentemente da ciò a cui punta. Questo è il motivo per cui il polimorfismo di runtime deve sempre essere implementato con una sorta di puntatore, indipendentemente dal fatto che la tua lingua scelga di esporre quei puntatori a te. A differenza di Java, il linguaggio C ++ li espone.
Inoltre, i riferimenti possono essere assegnati a più di una volta. Quello che non puoi fare è creare un riferimento non inizializzato , cioè i puntatori possono essere nulli ma i riferimenti non possono.
Esattamente quale sintassi si utilizza dipende dal fatto che si vogliano riferimenti o puntatori grezzi o puntatori intelligenti, che è bisogno di capire in C ++ ma non nei linguaggi raccolti in garbage in Java (sul serio, è non facoltativo, leggi C ++ e / o C ++ moderno efficace per un corso accelerato su questo e altro materiale da richiedere). Ma ecco un semplice esempio per iniziare:
#include <iostream>
#include <memory>
using namespace std;
class Base {
public:
virtual int foo() {
return 1;
};
};
class Derived : public Base {
public:
int foo() {
return 2;
};
};
int main() {
Base b;
cout << b.foo() << endl; // prints 1
Derived d;
cout << d.foo() << endl; // prints 2
b = d;
cout << b.foo() << endl; // prints 1
// Because b is not a pointer, the Derived object
// gets "sliced" by the assignment.
Base& br = b;
cout << br.foo() << endl; // prints 1
Base& dr = d;
cout << dr.foo() << endl; // prints 2 because polymorphism
unique_ptr<Base> up1 = make_unique<Base>();
cout << up1->foo() << endl; // prints 1
unique_ptr<Base> up2 = make_unique<Derived>();
cout << up2->foo() << endl; // prints 2 because polymorphism
return 0;
}