C++에서 가상 및 순수 가상 기능의 차이점
이 기사에서는 C++의 가상 기능과 순수 가상 기능의 차이점을 설명합니다.
C++의 가상 기능과 그 특성
가상 기능은 다형성의 개념과 밀접한 관련이 있습니다. C++에서는 일부 데이터 멤버를 공유하고 인터페이스로 노출 된 동일한 멤버 함수를 가질 수있는 링크 된 계층 구조에서 다른 클래스를 구성 할 수 있습니다.
일반적으로 다른 클래스에서 코드의 일부를 상속하는 클래스를 파생 클래스라고하는 반면 상속 된 클래스는 기본 클래스입니다. 때때로 이러한 용어는 부모-자식 또는 슈퍼 클래스-서브 클래스 이름과 상호 교환 적으로 사용될 수 있습니다. 파생 클래스에서 재정의 할 수있는 함수를 가상 함수라고하며virtual
키워드로 선언됩니다. 가상 함수는 지정된 클래스 계층 구조 내에서 동일한 이름을 가지며 모든 파생 클래스는 함수에 대한 자체 정의를 구현할 수 있습니다.
함수가 재정의되지 않은 경우 파생 클래스 개체는 기본 클래스에 정의 된 함수를 호출합니다. 아래의 예제 프로그램은Engineer
및Employee
클래스 모두에서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
와 함께Triangle
및Rectangle
클래스를 구현합니다. 이 경우 두 파생 클래스에서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
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