Video: Limbajul C++ - problema rezolvata 13 - vectori 2024
În C ++, doar pentru că credeți că un anumit apel de funcție este legat târziu, nu înseamnă că acesta este. Dacă nu sunt declarate cu aceleași argumente în subclasele, funcțiile membrilor nu sunt suprasolicitate polimorfic, indiferent dacă sunt sau nu declarate virtuale.
O excepție de la aceeași regulă a declarației este că dacă funcția membră din clasa de bază returnează un pointer sau o referință la un obiect de clasă de bază, o funcție a elementului suprascris într-o subclasă poate returna un pointer sau o referință la un obiect din subclasa. Cu alte cuvinte, funcția makeACopy () este polimorfă, chiar dacă tipul de retur al celor două funcții diferă:
class Base {public: // returnați o copie a obiectului curent Base * makeACopy ();}; clasă Subclasa: public Base {public: // returnează o copie a obiectului curent SubClass * makeACopy ();}; void fn (Base & bc) {Bază * pCopy = bc. fa o copie(); // continuați …}
În practică, acest lucru este destul de natural. O funcție makeACopy () ar trebui să returneze un obiect de tip SubClass , chiar dacă s-ar putea să înlocuiască BaseClass:: makeACopy () .
Această afacere de a decide în tăcere când o funcție este suprascrisă și când nu este o sursă de eroare în C ++; atât de mult încât standardul din 2011 a introdus descriptorul suprascrie pe care programatorul îl poate folosi pentru a indica intenția sa de a suprascrie o funcție de clasă de bază.
C ++ generează o eroare de compilator dacă o funcție este declarată suprascrisă, dar, de fapt, nu suprascrie o funcție de clasă de bază din anumite motive (cum ar fi un argument nepotrivit) ca în exemplul următor: >
Acest fragment generează o eroare de compilare, deoarece metoda GradStudent:: addCourseGrade (float) a fost declarată suprascrisă, dar nu înlocuiește funcția de bază a clasei Student:: addCourseGrade (dublu) t meci.
final
, chiar dacă această funcție în sine suprascrie o funcție de clasă de bază anterioară, așa cum se demonstrează în următoarele suplimentar > PostDoc clasa: clasa GradStudent: public Student {public: virtual void addCourseGrade (dublu grad) final;}; clasa PostDoc: public GradStudent {public: virtual void addCourseGrade (grad dublu);}; Din moment ce Student:: addCourseGrade () este marcat final ,
declarația PostDoc:: addCourseGrade () generează o eroare deoarece încearcă să suprascrie metoda
Student . Aceasta afectează mai mult decât doar metodele virtuale ale clasei. O clasă
finală nu poate fi moștenită deloc.