È corretto; la func che hai definito in MyClass4 non ha lo stesso prototipo di quella dichiarata come virtuale pura in MyClass3, per cui hai semplicemente aggiunto un overload, non hai implementato la funzione virtuale. Ne segue che MyClass4 rimane una classe astratta, che non può essere istanziata.
Nota che in C++ è possibile implementare una funzione virtuale specificando un tipo restituito di classe più derivata, dato che C++ consente la covarianza rispetto al tipo restituito; in altre parole, è possibile fare:
La covarianza rispetto al tipo restituito è sempre consentita dato che la classe derivata fornisce più garanzie rispetto a quanto richiesto dal contratto dell'interfaccia; in altre parole, se chiamo func() su un'istanza di B tramite un puntatore ad A è corretto che mi vengano restituiti dei B*, visto che B deriva da A. Viceversa, il tuo caso non è consentito, dato che si potrebbe chiamare la func di un'istanza di MyClass4 tramite un MyClass3, per cui MyClass4::func potrebbe ricevere come secondo argomento un puntatore a MyClass3 quando il suo prototipo richiede una MyClass4 (più specifica).codice:class A { virtual A* func()=0; }; class B : public A { virtual B* func() { return new B; } };