Junior
Cosa sai della parola chiave virtuale in C++?
sobes.tech AI
Risposta dell'AI
virtual in C++ viene utilizzato per dichiarare funzioni virtuali nella classe base. Questo consente di implementare il polimorfismo in fase di esecuzione (polimorfismo runtime).
Applicazione:
- Definisce una funzione nella classe base che può essere sovrascritta (override) nelle classi derivate.
- Quando una funzione virtuale viene chiamata tramite un puntatore o riferimento alla classe base, in realtà viene chiamata l'implementazione della funzione nell'oggetto della classe derivata (se è stata sovrascritta). Questo avviene in fase di esecuzione tramite la tabella delle funzioni virtuali (vtable).
Punti chiave:
- Solo le funzioni membro di classe possono essere virtuali. Le funzioni globali, le funzioni membro statiche e i costruttori non possono essere virtuali.
- I distruttori possono e devono spesso essere virtuali per evitare perdite di memoria durante l'eliminazione di oggetti di classi derivate tramite un puntatore alla classe base.
- Se una funzione è dichiarata
virtualnella classe base, rimane automaticamente virtuale in tutte le classi derivate, anche se non si utilizza esplicitamente la parola chiavevirtual(anche se si consiglia di usarevirtualeoverridenelle classi derivate per maggiore chiarezza). - Le funzioni virtuali pure sono dichiarate con
= 0e rendono la classe astratta. Una tale classe non può essere istanziata direttamente.
Esempio:
#include <iostream>
class Base {
public:
virtual void print() {
std::cout << "Da Base" << std::endl;
}
virtual ~Base() {
std::cout << "Distruttore di Base" << std::endl;
}
};
class Derived : public Base {
public:
void print() override { // Uso di override per indicare chiaramente la sovrascrittura
std::cout << "Da Derived" << std::endl;
}
~Derived() override { // Uso di override
std::cout << "Distruttore di Derived" << std::endl;
}
};
int main() {
Base* ptr = new Derived(); // Puntatore alla classe base che punta a un oggetto derivato
ptr->print(); // Viene chiamato Derived::print() grazie alla funzione virtuale
delete ptr; // Vengono chiamati i distruttori di Derived e poi di Base grazie al distruttore virtuale
return 0;
}
Concetti correlati:
- vtable (tabella delle funzioni virtuali): Tabella di puntatori alle funzioni virtuali della classe. Ogni oggetto con funzioni virtuali contiene un puntatore invisibile (vptr) alla vtable della sua classe.
- vptr (puntatore alla vtable): Necessario per determinare quale funzione chiamare in fase di esecuzione.
= 0(funzione virtuale pura): Indica che la funzione non ha implementazione in questa classe, rendendola astratta.override(specificatore di sovrascrittura): Indica esplicitamente che la funzione nella classe derivata sovrascrive una funzione virtuale della classe base. Aiuta il compilatore a trovare errori se la firma non corrisponde.final(specificatore): Impedisce ulteriori sovrascritture di funzioni virtuali o ereditarietà dalla classe.
In breve: virtual è il meccanismo principale per implementare il polimorfismo tramite ereditarietà e binding dinamico in C++.