C++에서 가상 및 순수 가상 기능의 차이점

Jinku Hu 2023년10월12일
  1. C++의 가상 기능과 그 특성
  2. C++의 순수 가상 함수 및 추상 유형
C++에서 가상 및 순수 가상 기능의 차이점

이 기사에서는 C++의 가상 기능과 순수 가상 기능의 차이점을 설명합니다.

C++의 가상 기능과 그 특성

가상 기능은 다형성의 개념과 밀접한 관련이 있습니다. C++에서는 일부 데이터 멤버를 공유하고 인터페이스로 노출 된 동일한 멤버 함수를 가질 수있는 링크 된 계층 구조에서 다른 클래스를 구성 할 수 있습니다.

일반적으로 다른 클래스에서 코드의 일부를 상속하는 클래스를 파생 클래스라고하는 반면 상속 된 클래스는 기본 클래스입니다. 때때로 이러한 용어는 부모-자식 또는 슈퍼 클래스-서브 클래스 이름과 상호 교환 적으로 사용될 수 있습니다. 파생 클래스에서 재정의 할 수있는 함수를 가상 함수라고하며virtual키워드로 선언됩니다. 가상 함수는 지정된 클래스 계층 구조 내에서 동일한 이름을 가지며 모든 파생 클래스는 함수에 대한 자체 정의를 구현할 수 있습니다.

함수가 재정의되지 않은 경우 파생 클래스 개체는 기본 클래스에 정의 된 함수를 호출합니다. 아래의 예제 프로그램은EngineerEmployee클래스 모두에서print함수를 정의하여 가상 함수의 기본 사용법을 보여줍니다. 그런 다음Employee에 대한 참조를 받아들이고 본문 내에서print함수를 호출하는 임의의 함수Func를 구현할 수 있습니다.

이제Func구현은 여러 번 변경 될 수 있지만 항상 매개 변수로 전달되는 객체를 기반으로 해당print함수를 호출합니다. Employee클래스 계층 구조에 여러 파생 클래스를 추가 할 수 있습니다. 각각은print기능을 구현하거나 구현하지 않을 수 있지만Func함수는 해당 인스턴스를 수락하고 올바른 가상 기능을 호출합니다.

#include <iostream>
#include <string>

using std::cin;
using std::cout;
using std::endl;
using std::string;

class Employee {
 public:
  Employee(string fn, string ln)
      : first_name(std::move(fn)), last_name(std::move(ln)) {}
  virtual void print() {
    cout << "name: " << first_name << "\n"
         << "last name: " << last_name << "\n";
  };

 protected:
  string first_name, last_name;
};

class Engineer : public Employee {
 public:
  Engineer(string fn, string ln, string sp)
      : Employee(std::move(fn), std::move(ln)), specialization(std::move(sp)) {}

  void print() override {
    Employee::print();
    cout << "specialization: " << specialization << "\n";
  }

 private:
  string specialization;
};

void Func(Employee &em) { em.print(); }

int main() {
  Employee em1("Jim", "Jiao");
  Engineer eng1("Jin", "Baker", "Aerospace Engineering");

  Func(em1);
  cout << "\n";
  Func(eng1);

  return EXIT_SUCCESS;
}

출력:

name: Jim
last name: Jiao

name: Jin
last name: Baker
specialization: Aerospace Engineering

C++의 순수 가상 함수 및 추상 유형

반면에 우리는 순수 가상 함수의 개념을 가지고 있는데, 이것은 일반 가상 함수와 유사하게 선언되고= 0;표기법을 포함합니다. 선언 끝에. 이러한 함수는 기본적으로 먼저 선언되는 기본 클래스에 정의가 없습니다. 따라서 파생 클래스에서 대부분 정의됩니다.

순수 가상 함수를 포함하는 클래스를 추상 클래스라고하며 일반적으로 파생 클래스의 인터페이스를 지정하는 데 사용됩니다. 추상 클래스는 직접 인스턴스화 할 수 없습니다.

다음 코드 스 니펫은 추상 기본 클래스Shape와 함께TriangleRectangle클래스를 구현합니다. 이 경우 두 파생 클래스에서printArea순수 가상 함수를 정의했습니다. 때로는 파생 클래스가 상속 된 순수 가상 함수를 정의하지 않아 주어진 클래스 계층 구조에서 다른 추상 클래스가 될 수 있습니다. 파생 클래스는 여러 순수 가상 함수를 상속 할 수 있습니다. 둘 중 하나라도 정의하지 않으면 클래스에 추상 분류가 적용됩니다.

#include <iostream>
#include <string>
#include <vector>

using std::cout;
using std::endl;
using std::string;
using std::vector;

class Shape {
 public:
  virtual void printArea() = 0;
};

class Triangle : public Shape {
 public:
  Triangle(double b, double h) : base(b), height(h) {}

  void printArea() override { cout << (base * height) / 2.0; }

 private:
  double base;
  double height;
};

class Rectangle : public Shape {
 public:
  Rectangle(double i1, double i2) : edges({i1, i2}) {}

  void printArea() override { cout << edges[0] * edges[1]; }

 private:
  vector<double> edges;
};

int main() {
  Triangle t1(3, 5);
  t1.printArea();
  cout << "\n";

  Rectangle r1(3, 5);
  r1.printArea();
  cout << "\n";

  return EXIT_SUCCESS;
}

출력:

7.5
15
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

관련 문장 - C++ Function