Ugrás a tartalomhoz

override keyword

A Wikiszótárból, a nyitott szótárból

Főnév

[szerkesztés]

override keyword (tsz. override keywords)

  1. (informatika)

override kulcsszó C++-ban

[szerkesztés]

1. Bevezetés

[szerkesztés]

A override kulcsszó a C++11 verziójától kezdve elérhető. Segít biztosítani, hogy egy leszármazott osztály egy virtuális függvényt ténylegesen felüldefiniál (override) az ősosztályban, és nem hoz létre egy új, véletlenül hasonló nevű függvényt.



2. Miért hasznos az override?

[szerkesztés]

Az override segít az alábbi problémák elkerülésében:

  1. Hibás függvénynév: Ha véletlenül más nevet adunk a metódusnak a leszármazott osztályban, akkor az ősosztály metódusa nem lesz felüldefiniálva.
  2. Hibás szignatúra: Ha a paraméterek típusa nem pontosan egyezik az ősosztálybeli metódussal, az nem fog felüldefiniálásnak számítani, és a C++ egy új metódusként kezeli.
  3. Fordítási hibát generál: Ha egy metódust override kulcsszóval jelölünk, de nincs megfelelő függvény az ősosztályban, a fordító hibát jelez.



3. Alapvető használat

[szerkesztés]

Az alábbi példában egy virtuális függvényt felüldefiniálunk override használatával:

#include <iostream>
using namespace std;

class Szulo {
public:
    virtual void uzenet() {  // Virtuális függvény
        cout << "Szülőosztály üzenete." << endl;
    }
};

class Gyermek : public Szulo {
public:
    void uzenet() override {  // Felüldefiniálás
        cout << "Gyermekosztály üzenete." << endl;
    }
};

int main() {
    Szulo* obj = new Gyermek();
    obj->uzenet();  // A gyermek osztály metódusa hívódik meg
    delete obj;
    return 0;
}

Kimenet:

Gyermekosztály üzenete.

Itt az uzenet() függvényt az override kulcsszóval jelöltük, így a fordító ellenőrzi, hogy ténylegesen egy virtuális függvényt írunk-e felül.



4. override nélkül - mi lehet a probléma?

[szerkesztés]

Ha véletlenül elírjuk a függvény nevét vagy annak szignatúráját, a fordító nem fog figyelmeztetni, és a kód váratlanul viselkedhet:

class Szulo {
public:
    virtual void uzenet() {
        cout << "Szülőosztály üzenete." << endl;
    }
};

class Gyermek : public Szulo {
public:
    void Uzenet() {  // Figyeljük meg, hogy a név eltér (nagybetűs "Uzenet")
        cout << "Gyermekosztály üzenete." << endl;
    }
};

int main() {
    Szulo* obj = new Gyermek();
    obj->uzenet();  // Nem a gyermek metódusa hívódik meg, hanem az ősosztályé!
    delete obj;
    return 0;
}

Kimenet:

Szülőosztály üzenete.

Ez azért történik, mert az Uzenet() függvény nem felel meg az ősosztály uzenet() függvényének, így a fordító nem kezeli felüldefiniálásként. Ha override-ot használnánk, a fordító hibát jelezne:

void Uzenet() override { // Fordítási hiba, mert nincs ilyen nevű virtuális függvény!

5. Hibás szignatúra és override

[szerkesztés]

A függvény szignatúrájának változtatása szintén problémát okozhat:

class Szulo {
public:
    virtual void uzenet(int x) { // Egy paramétert vár
        cout << "Szülőosztály üzenete: " << x << endl;
    }
};

class Gyermek : public Szulo {
public:
    void uzenet() override { // Hibás! A paraméterlistának egyeznie kellene
        cout << "Gyermekosztály üzenete." << endl;
    }
};

Fordítási hiba:

error: ‘void Gyermek::uzenet()’ marked ‘override’, but does not override any member functions

A helyes verzió:

void uzenet(int x) override {

6. final kulcsszóval kombinálva

[szerkesztés]

A final kulcsszóval megtilthatjuk a további felüldefiniálást:

class Szulo {
public:
    virtual void uzenet() final {  // Ezt nem lehet tovább felüldefiniálni
        cout << "Szülőosztály végleges üzenete." << endl;
    }
};

class Gyermek : public Szulo {
public:
    // void uzenet() override {  // Hibát ad, mert az ősosztályban final-ként van megadva
    //     cout << "Gyermekosztály üzenete." << endl;
    // }
};

7. Többszörös öröklődés és override

[szerkesztés]

Ha egy osztály több szülőosztályból örököl azonos nevű virtuális függvényeket, akkor a gyermekosztálynak fel kell oldania az ütközést:

class A {
public:
    virtual void uzenet() {
        cout << "A osztály üzenete." << endl;
    }
};

class B {
public:
    virtual void uzenet() {
        cout << "B osztály üzenete." << endl;
    }
};

class C : public A, public B {
public:
    void uzenet() override {  // Egyértelműsíteni kell, hogy melyik szülő függvényét definiáljuk felül
        cout << "C osztály saját üzenete." << endl;
    }
};

int main() {
    C obj;
    obj.uzenet();  // "C osztály saját üzenete."
    return 0;
}

Kimenet:

C osztály saját üzenete.

Ha nem definiáljuk felül az uzenet() metódust a C osztályban, akkor fordítási hibát kapunk, mert a fordító nem tudja eldönteni, hogy az A::uzenet() vagy a B::uzenet() metódust kellene hívnia.



8. Összegzés

[szerkesztés]
  • A override kulcsszó biztosítja, hogy egy metódus valóban felülír egy ősosztálybeli virtuális függvényt.
  • Segít elkerülni a hibákat, például az elírásokat vagy a szignatúra eltéréseket.
  • Fordítási hibát okoz, ha nincs megfelelő virtuális függvény az ősosztályban.
  • Együtt használható final-lal, hogy megakadályozzuk a további felüldefiniálást.
  • Többszörös öröklődés esetén segít feloldani az ütközéseket.

A override használata ajánlott minden virtuális függvény felüldefiniálásánál, hogy elkerüljük a nem szándékos hibákat és félreértéseket! 🚀