산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> C 언어

C++ 가상 함수

C++ 가상 함수

이 튜토리얼에서는 예제를 통해 C++ 가상 함수와 그 사용법에 대해 알아볼 것입니다.

가상 함수는 파생 클래스에서 재정의할 것으로 예상되는 기본 클래스의 멤버 함수입니다.

기본적으로 가상 함수는 함수가 재정의되도록 하기 위해 기본 클래스에서 사용됩니다. . 이것은 특히 기본 클래스의 포인터가 파생 클래스의 개체를 가리키는 경우에 적용됩니다.

예를 들어, 아래 코드를 고려하십시오.

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

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

나중에 Base 포인터를 생성하면 Derived의 개체를 가리키는 유형 클래스를 호출하고 print() 함수를 호출하면 print() Base의 기능 수업.

즉, Base의 멤버 함수는 재정의되지 않습니다.

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

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

    return 0;
}

이를 피하기 위해 print()를 선언합니다. Base의 기능 virtual를 사용하여 가상 클래스 키워드.

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

가상 함수는 C++에서 다형성의 필수적인 부분입니다. 자세히 알아보려면 C++ 다형성에 대한 자습서를 확인하세요.

<시간>

예제 1:C++ 가상 함수

#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;
}

출력

Derived Function

여기에서 print()을 선언했습니다. Base의 기능 virtual로 .

따라서 이 함수는 Base 포인터를 사용하는 경우에도 재정의됩니다. Derived를 가리키는 유형 개체 파생1 .

<그림> <시간>

C++ 재정의 식별자

C++ 11은 새로운 식별자 override를 제공했습니다. 가상 기능을 사용하는 동안 버그를 방지하는 데 매우 유용합니다.

이 식별자는 기본 클래스의 멤버 함수를 재정의하는 파생 클래스의 멤버 함수를 지정합니다.

예를 들어,

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

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

Derived에서 함수 프로토타입을 사용하는 경우 클래스 외부에서 해당 함수를 정의한 다음 다음 코드를 사용합니다.

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

// function definition
void Derived::print() {
    // code
}
<시간>

C++ 재정의 사용

가상 함수를 사용할 때 파생 클래스의 멤버 함수를 선언할 때 실수가 있을 수 있습니다.

override 사용 식별자는 이러한 실수가 발생했을 때 오류 메시지를 표시하도록 컴파일러에 프롬프트합니다.

그렇지 않으면 프로그램은 단순히 컴파일되지만 가상 기능은 무시되지 않습니다.

이러한 가능한 실수 중 일부는 다음과 같습니다.

<시간>

C++ 가상 기능 사용

기본 클래스 Animal이 있다고 가정합니다. 및 파생 클래스 DogCat .

각 클래스에 type이라는 데이터 멤버가 있다고 가정합니다. . 이러한 변수가 각각의 생성자를 통해 초기화된다고 가정합니다.

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") {}
    ... .. ...
};

이제 프로그램에서 두 개의 public 각 클래스에 대한 기능:

  1. getType() 유형의 값을 반환하려면
  2. print() type의 값을 출력하려면

각 클래스에서 이 두 함수를 별도로 생성하고 재정의할 수 있습니다. 이는 길고 지루할 것입니다.

또는 getType()를 만들 수 있습니다. 가상 Animal 클래스를 만든 다음 별도의 단일 print()을 만듭니다. Animal 포인터를 받는 함수 인수로 입력하십시오. 그런 다음 이 단일 기능을 사용하여 가상 기능을 재정의할 수 있습니다.

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

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

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

이렇게 하면 코드가 더 짧아집니다 , 청소기 , 및 덜 반복적 .

<시간>

예제 2:C++ 가상 함수 데모

// 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;
}

출력

Animal: Animal
Animal: Dog
Animal: Cat

여기서는 가상 함수 getType()을 사용했습니다. 및 Animal 포인터 ani print() 반복을 피하기 위해 모든 클래스에서 사용할 수 있습니다.

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

main()에서 , 3개의 Animal를 만들었습니다. Animal 객체를 동적으로 생성하기 위한 포인터 , DogCat 수업.

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

그런 다음 print() 다음 포인터를 사용하는 함수:

  1. print(animal1)일 때 가 호출되면 포인터가 Animal을 가리킵니다. 물체. 따라서 Animal의 가상 함수는 클래스는 print() 내부에서 실행됩니다. .
  2. print(dog1)일 때 가 호출되면 포인터가 Dog를 가리킵니다. 물체. 따라서 가상 기능이 재정의되고 Dog의 기능이 print() 내부에서 실행됩니다. .
  3. print(cat1)일 때 가 호출되면 포인터가 Cat을 가리킵니다. 물체. 따라서 가상 기능은 재정의되고 Cat의 기능은 print() 내부에서 실행됩니다. .

C 언어

  1. C++ 프로그래밍에서 함수에 배열 전달
  2. C++ 클래스 및 개체
  3. C++ friend 함수 및 friend 클래스
  4. C++ 클래스 템플릿
  5. 프로그램 예제가 있는 C++ 함수
  6. Verilog 기능
  7. C - 기능
  8. C++의 스토리지 클래스
  9. C++ 오버로딩(연산자와 함수)
  10. C++의 다형성