Non è possibile, ma è solo perché un'omissione. Non è qualcosa che "non ha senso", come molti sostengono. Per essere chiari, sto parlando di qualcosa del genere:
struct Base {
static virtual void sayMyName() {
cout << "Base\n";
}
};
struct Derived : public Base {
static void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
Derived::sayMyName(); // Also would work.
}
Questo è al 100% qualcosa che potrebbe essere implementato (semplicemente non l'ha fatto), e direi qualcosa di utile.
Considera come funzionano le normali funzioni virtuali. Rimuovi la statics e aggiungi alcune altre cose e abbiamo:
struct Base {
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
void sayMyName() override {
cout << "Derived\n";
}
};
void foo(Base *b) {
b->sayMyName();
}
Funziona bene e in pratica ciò che accade è che il compilatore crea due tabelle, chiamate VTables, e assegna indici alle funzioni virtuali come questa
enum Base_Virtual_Functions {
sayMyName = 0;
foo = 1;
};
using VTable = void*[];
const VTable Base_VTable = {
&Base::sayMyName,
&Base::foo
};
const VTable Derived_VTable = {
&Derived::sayMyName,
&Base::foo
};
Successivamente ogni classe con funzioni virtuali viene aumentata con un altro campo che punta al suo VTable, quindi il compilatore sostanzialmente li cambia in questo modo:
struct Base {
VTable* vtable;
virtual void sayMyName() {
cout << "Base\n";
}
virtual void foo() {
}
int somedata;
};
struct Derived : public Base {
VTable* vtable;
void sayMyName() override {
cout << "Derived\n";
}
};
Quindi cosa succede realmente quando chiami b->sayMyName()? Fondamentalmente questo:
b->vtable[Base_Virtual_Functions::sayMyName](b);
(Il primo parametro diventa this.)
Ok bene, quindi come funzionerebbe con le funzioni virtuali statiche? Bene, qual è la differenza tra le funzioni membro statiche e non statiche? L'unica differenza è che quest'ultimo ottiene un thispuntatore.
Possiamo fare esattamente lo stesso con le funzioni virtuali statiche: basta rimuovere il thispuntatore.
b->vtable[Base_Virtual_Functions::sayMyName]();
Questo potrebbe quindi supportare entrambe le sintassi:
b->sayMyName(); // Prints "Base" or "Derived"...
Base::sayMyName(); // Always prints "Base".
Quindi ignora tutti gli oppositori. Si fa senso. Perché non è supportato allora? Penso che sia perché ha pochissimi benefici e potrebbe anche essere un po 'confuso.
L'unico vantaggio tecnico rispetto a una normale funzione virtuale è che non è necessario passare thisalla funzione, ma non credo che farebbe alcuna differenza misurabile per le prestazioni.
Significa che non hai una funzione statica e non statica separata per i casi in cui hai un'istanza e quando non hai un'istanza, ma potrebbe anche confondere il fatto che sia veramente "virtuale" solo quando usi la chiamata di istanza.
constfirma in un metodo contrassegna ilthispuntatore implicito come costante e non può essere applicato ai metodi statici poiché mancano del parametro implicito.