Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> C Taal

C++ virtuele functies

C++ virtuele functies

In deze zelfstudie leren we over de virtuele C++-functie en het gebruik ervan met behulp van voorbeelden.

Een virtuele functie is een lidfunctie in de basisklasse die we verwachten te herdefiniëren in afgeleide klassen.

In de basisklasse wordt in principe een virtuele functie gebruikt om ervoor te zorgen dat de functie overschreven wordt. . Dit is vooral van toepassing op gevallen waarin een pointer van de basisklasse naar een object van een afgeleide klasse wijst.

Beschouw bijvoorbeeld de onderstaande code:

class Base {
   public:
    void print() {
        // code
    }
};

class Derived : public Base {
   public:
    void print() {
        // code
    }
};

Later, als we een pointer van Base . maken type om te verwijzen naar een object van Derived klas en bel de print() functie, roept het de print() functie van de Base klasse.

Met andere woorden, de ledenfunctie van Base wordt niet overschreven.

int main() {
    Derived derived1;
    Base* base1 = &derived1;

    // calls function of Base class
    base1->print();

    return 0;
}

Om dit te voorkomen, declareren we de print() functie van de Base class als virtueel met behulp van de virtual zoekwoord.

class Base {
   public:
    virtual void print() {
        // code
    }
};

Virtuele functies zijn een integraal onderdeel van polymorfisme in C++. Bekijk onze tutorial over C++ polymorfisme voor meer informatie.


Voorbeeld 1:virtuele C++-functie

#include <iostream>
using namespace std;

class Base {
   public:
    virtual void print() {
        cout << "Base Function" << endl;
    }
};

class Derived : public Base {
   public:
    void print() {
        cout << "Derived Function" << endl;
    }
};

int main() {
    Derived derived1;

    // pointer of Base type that points to derived1
    Base* base1 = &derived1;

    // calls member function of Derived class
    base1->print();

    return 0;
}

Uitvoer

Derived Function

Hier hebben we de print() . gedeclareerd functie van Base als virtual .

Deze functie wordt dus overschreven, zelfs als we een aanwijzer van Base . gebruiken type dat verwijst naar de Derived object afgeleid1 .


C++ override Identifier

C++ 11 heeft ons een nieuwe identifier gegeven override dat is erg handig om bugs te voorkomen tijdens het gebruik van virtuele functies.

Deze identifier specificeert de lidfuncties van de afgeleide klassen die de lidfunctie van de basisklasse overschrijven.

Bijvoorbeeld,

class Base {
   public:
    virtual void print() {
        // code
    }
};

class Derived : public Base {
   public:
    void print() override {
        // code
    }
};

Als we een functie-prototype gebruiken in Derived class en definieer die functie buiten de klasse, dan gebruiken we de volgende code:

class Derived : public Base {
   public:
    // function prototype
    void print() override;
};

// function definition
void Derived::print() {
    // code
}

Gebruik van C++ override

Bij het gebruik van virtuele functies is het mogelijk om fouten te maken bij het declareren van de lidfuncties van de afgeleide klassen.

De override . gebruiken identifier vraagt ​​de compiler om foutmeldingen weer te geven wanneer deze fouten worden gemaakt.

Anders zal het programma gewoon compileren, maar de virtuele functie wordt niet overschreven.

Enkele van deze mogelijke fouten zijn:

  • Functies met onjuiste namen: Als de virtuele functie in de basisklasse bijvoorbeeld print() . heet , maar we noemen per ongeluk de overschrijvende functie in de afgeleide klasse als pint() .
  • Functies met verschillende retourtypes: Als de virtuele functie bijvoorbeeld van void . is type maar de functie in de afgeleide klasse is van int typ.
  • Functies met verschillende parameters: Als de parameters van de virtuele functie en de functies in de afgeleide klassen niet overeenkomen.
  • Er is geen virtuele functie gedeclareerd in de basisklasse.

Gebruik van virtuele C++-functies

Stel we hebben een basisklasse Animal en afgeleide klassen Dog en Cat .

Stel dat elke klasse een gegevenslid heeft met de naam type . Stel dat deze variabelen worden geïnitialiseerd via hun respectievelijke constructors.

class Animal {
   private:
    string type;
    ... .. ...
    public:
      Animal(): type("Animal") {}
    ... .. ...
};

class Dog : public Animal {
   private:
    string type;
    ... .. ...
    public:
      Animal(): type("Dog") {}
    ... .. ...
};

class Cat : public Animal {
   private:
    string type;
      ... .. ...
    public:
      Animal(): type("Cat") {}
    ... .. ...
};

Laten we nu aannemen dat ons programma vereist dat we twee public functies voor elke klasse:

  1. getType() om de waarde van type te retourneren
  2. print() om de waarde van type af te drukken

We zouden beide functies in elke klasse afzonderlijk kunnen maken en ze kunnen negeren, wat lang en vervelend zal zijn.

Of we kunnen getType() . maken virtueel in de Animal class en maak vervolgens een enkele, aparte print() functie die een pointer van Animal . accepteert typ als argument. We kunnen dan deze enkele functie gebruiken om de virtuele functie te overschrijven.

class Animal {
    ... .. ...
   public:
    ... .. ...
    virtual string getType {...}
};

... .. ...
... .. ...

void print(Animal* ani) {
    cout << "Animal: " << ani->getType() << endl;
}

Dit maakt de code korter , schonere , en minder repetitief .


Voorbeeld 2:C++ virtuele functiedemonstratie

// C++ program to demonstrate the use of virtual function

#include <iostream>
#include <string>
using namespace std;

class Animal {
   private:
    string type;

   public:
    // constructor to initialize type
    Animal() : type("Animal") {}

    // declare virtual function
    virtual string getType() {
        return type;
    }
};

class Dog : public Animal {
   private:
    string type;

   public:
    // constructor to initialize type
    Dog() : type("Dog") {}

    string getType() override {
        return type;
    }
};

class Cat : public Animal {
   private:
    string type;

   public:
    // constructor to initialize type
    Cat() : type("Cat") {}

    string getType() override {
        return type;
    }
};

void print(Animal* ani) {
    cout << "Animal: " << ani->getType() << endl;
}

int main() {
    Animal* animal1 = new Animal();
    Animal* dog1 = new Dog();
    Animal* cat1 = new Cat();

    print(animal1);
    print(dog1);
    print(cat1);

    return 0;
}

Uitvoer

Animal: Animal
Animal: Dog
Animal: Cat

Hier hebben we de virtuele functie getType() . gebruikt en een Animal pointer ani om herhaling van de print() . te voorkomen functie in elke klas.

void print(Animal* ani) {
    cout << "Animal: " << ani->getType() << endl;
}

In main() , we hebben 3 Animal . gemaakt pointers om dynamisch objecten van Animal . te maken , Dog en Cat lessen.

// dynamically create objects using Animal pointers
Animal* animal1 = new Animal();
Animal* dog1 = new Dog();
Animal* cat1 = new Cat();

We noemen dan de print() functie met behulp van deze aanwijzingen:

  1. Wanneer print(animal1) wordt aangeroepen, wijst de aanwijzer naar een Animal object. Dus de virtuele functie in Animal class wordt uitgevoerd binnen print() .
  2. Wanneer print(dog1) wordt aangeroepen, wijst de aanwijzer naar een Dog object. Dus de virtuele functie wordt overschreven en de functie van Dog wordt uitgevoerd binnen print() .
  3. Wanneer print(cat1) wordt aangeroepen, wijst de aanwijzer naar een Cat object. Dus de virtuele functie wordt overschreven en de functie van Cat wordt uitgevoerd binnen print() .

C Taal

  1. Array doorgeven aan een functie in C++-programmering
  2. C++ klassen en objecten
  3. C++ vriend Functie en vriend Klassen
  4. C++-klassesjablonen
  5. C++-functies met programmavoorbeelden
  6. Verilog-functies
  7. C - Functies
  8. Opslagklassen in C++
  9. C++ overbelasting (operator en functie)
  10. Polymorfisme in C++
  11. Gegevensabstractie in C++