polymorphism c
예제와 함께 C ++에서 다형성의 역할.
다형성은 객체 지향 프로그래밍의 네 가지 기둥 중 하나입니다. 다형성은 다양한 형태를 갖는 것을 의미합니다. 상황에 따라 사물이 다양한 형태를 취할 수있는 기법으로 정의 할 수있다.
프로그래밍 용어로 객체가 다른 조건에서 다르게 행동 할 수 있다고 말할 수 있습니다.
이 튜토리얼에서는 다형성의 유형, 다형성의 다양한 다른 개념과 함께 다형성을 구현하는 방법에 대해 자세히 알아 봅니다.
=> 여기에서 C ++ 교육 자습서의 A-Z를 보려면 여기를 확인하십시오.
예를 들어, 여성은 다양한 상황에서 많은 역할을 할 수 있습니다. 아이에게 그녀는 어머니, 집안 주부, 사무실 일꾼 등이다. 그래서 여성은 다른 역할을 맡고 다른 조건에서 다른 행동을 보인다. 이것은 다형성의 실제 예입니다.
마찬가지로 프로그래밍 세계에서도 피연산자가 변경 될 때 다르게 동작하는 이진 더하기 연산자 인 '+'연산자를 가질 수 있습니다. 예를 들어, 두 피연산자가 모두 숫자이면 더하기를 수행합니다.
반면에 피연산자가 문자열이면 연결 연산자로 작동합니다. 따라서 다형성은 간단히 말해서 여러 형태를 취하거나 다른 조건에서 다르게 행동하는 실체를 의미합니다.
학습 내용 :
다형성의 유형
다형성은 두 가지 유형으로 나뉩니다.
- 컴파일 시간 다형성
- 런타임 다형성
이를 나타내는 다이어그램은 다음과 같습니다.
위의 다이어그램에서 볼 수 있듯이 다형성은 컴파일 타임 다형성과 런타임 다형성으로 나뉩니다. 컴파일 시간 다형성은 연산자 오버로딩과 함수 오버로딩으로 더 나뉩니다. 런타임 다형성은 가상 함수를 사용하여 추가로 구현됩니다.
컴파일 시간 다형성은 초기 바인딩 또는 정적 다형성이라고도합니다. 이러한 유형의 다형성에서 객체의 메서드는 컴파일 시간에 호출됩니다. 런타임 다형성의 경우 객체의 메서드가 런타임에 호출됩니다.
런타임 다형성은 동적 또는 후기 바인딩 또는 동적 다형성이라고도합니다. 다음 주제에서 이러한 각 기술의 세부 구현을 살펴 보겠습니다.
컴파일 시간 다형성 대. 런타임 다형성
아래에서 컴파일 시간과 런타임 다형성의 주요 차이점을 살펴 보겠습니다.
컴파일 시간 다형성 | 런타임 다형성 |
---|---|
정적 다형성 또는 초기 바인딩이라고도합니다. | 동적 다형성 또는 후기 / 동적 바인딩이라고도합니다. |
Objects 메서드는 컴파일 타임에 호출됩니다. | 개체의 메서드는 런타임에 호출됩니다. |
일반적으로 연산자 오버로딩 및 함수 오버로딩을 사용하여 구현됩니다. | 가상 함수 및 메서드 재정의를 사용하여 구현 |
메서드 오버로딩은 둘 이상의 메서드가 이름은 같지만 매개 변수 목록 및 유형이 다를 수있는 컴파일 타임 다형성입니다. | 메서드 재정의는 두 개 이상의 메서드가 동일한 프로토 타입으로 동일한 이름을 갖는 런타임 다형성입니다. |
메서드는 컴파일 타임에 알려지기 때문에 실행이 더 빠릅니다. | 메서드가 런타임에 알려지기 때문에 실행 속도가 느립니다. |
컴파일 타임에 모든 것을 알아야하므로 솔루션 구현에 대한 유연성이 떨어집니다. | 메서드가 런타임에 결정되므로 복잡한 솔루션을 구현하는 데 훨씬 더 유연합니다. |
컴파일 시간 다형성
컴파일 시간 다형성은 객체의 메서드가 컴파일 시간에 호출되는 기술입니다.
이러한 유형의 다형성은 두 가지 방식으로 구현됩니다.
- 기능 과부하
- 연산자 오버로딩
각 기술에 대해 자세히 설명합니다.
함수 과부하
이름은 같지만 매개 변수 유형이 다르거 나 인수 수가 다른 함수가 두 개 이상있을 때 함수가 오버로드되었다고합니다.
따라서 매개 변수 유형, 매개 변수 순서 및 매개 변수 수에 따라 함수가 오버로드 될 수 있습니다.
이름과 매개 변수 목록이 같지만 반환 유형이 다른 두 함수는 오버로드 된 함수가 아니므로 프로그램에서 사용하면 컴파일 오류가 발생합니다.
마찬가지로 함수 매개 변수가 포인터에서만 다르고 배열 유형이 동일하면 오버로딩에 사용해서는 안됩니다.
정적 및 비 정적, const 및 volatile 등과 같은 다른 유형 또는 기본값의 존재 여부가 다른 매개 변수 선언도 구현 관점에서 동일하므로 오버로딩에 사용되지 않습니다.
다른 휴대 전화를 감시하는 앱
예를 들어,다음 함수 프로토 타입은 오버로드 된 함수입니다.
Add(int,int); Add(int,float); Add(float,int); Add(int,int,int);
위의 프로토 타입에서 매개 변수 유형, 매개 변수 순서 또는 순서, 매개 변수 수 등에 따라 Add 함수를 오버로드하는 것을 볼 수 있습니다.
함수 오버로딩을 더 잘 이해하기 위해 완전한 프로그래밍 예제를 살펴 보겠습니다.
#include #include using namespace std; class Summation { public: int Add(int num1,int num2) { return num1+num2; } int Add(int num1,int num2, int num3) { return num1+num2+num3; } string Add(string s1,string s2){ return s1+s2; } }; int main(void) { Summation obj; cout< 산출:
35
191
19
Hello World
위의 프로그램에는 두 개의 정수 인수, 세 개의 정수 인수 및 두 개의 문자열 인수를 취하는 Add라는 세 개의 오버로드 된 함수를 정의한 Summation 클래스가 있습니다.
주 함수에서 다양한 매개 변수를 제공하는 4 개의 함수 호출을 수행합니다. 처음 두 함수 호출은 간단합니다. Add에 대한 세 번째 함수 호출에서 두 개의 부동 소수점 값을 인수로 제공합니다.
이 경우 일치하는 함수는 내부적으로 int Add (int, int)이며 float는 double로 변환 된 다음 int 매개 변수가있는 함수와 일치됩니다. float 대신 double을 지정했다면 double을 매개 변수로 사용하는 또 다른 오버로드 된 함수를 갖게됩니다.
마지막 함수 호출은 문자열 값을 매개 변수로 사용합니다. 이 경우 추가 (+) 연산자는 연결 연산자 역할을하며 두 문자열 값을 연결하여 단일 문자열을 생성합니다.
함수 오버로딩의 이점
함수 오버로딩의 주요 이점은 코드 재사용을 촉진한다는 것입니다. 인수 유형, 인수 시퀀스 및 인수 수에 따라 오버로드되는 한 동일한 이름으로 가능한 많은 함수를 가질 수 있습니다.
이렇게하면 서로 다른 조건에서 동일한 작업의 동작을 나타내는 동일한 이름의 서로 다른 기능을 더 쉽게 사용할 수 있습니다.
함수 오버로딩이 없다면 이름이 다른 여러 종류의 함수를 너무 많이 작성해야했을 것입니다. 따라서 코드를 읽을 수없고 적응하기 어렵습니다.
연산자 오버로딩
연산자 오버로딩은 C ++의 기존 연산자에 다른 의미를 부여하는 기술입니다. 즉, 사용자 정의 데이터 유형에 객체로 특별한 의미를 부여하기 위해 연산자를 오버로드합니다.
C ++의 대부분의 연산자는 오버로드되거나 사용자 정의 데이터 유형에서 작동 할 수 있도록 특별한 의미가 부여됩니다. 오버로딩하는 동안 연산자의 기본 작업은 변경되지 않습니다. 오버로딩은 기본 의미를 동일하게 유지함으로써 연산자에게 추가적인 의미를 부여합니다.
대부분의 연산자는 C ++에서 오버로드 될 수 있지만 오버로드 할 수없는 연산자가 있습니다.
이러한 연산자는 아래 표에 나열되어 있습니다.
연산자 범위 해결 연산자 (: :) Sizeof 멤버 선택기 (.) 멤버 포인터 선택기 (*) 삼항 연산자 (? :)
연산자를 오버로드하는 데 사용하는 함수를 ' 운영자 기능 ”.
연산자 기능은 일반 기능과 유사하지만 차이점이 있습니다. 차이점은 연산자 함수의 이름이 키워드 ' 운영자 ”뒤에 오버로드 될 연산자 기호가옵니다.
그러면 해당 연산자가 프로그램에서 사용될 때 연산자 함수가 호출됩니다. 이러한 연산자 함수는 멤버 함수, 전역 메서드 또는 친구 함수일 수 있습니다.
연산자 함수의 일반 구문은 다음과 같습니다.
return_type classname::operator op(parameter list) { //function body }
여기서 'operator op'는 연산자가 키워드이고 op가 오버로드 될 연산자 인 연산자 함수입니다. Return_type은 반환 할 값 유형입니다.
연산자 함수를 사용하여 연산자 오버로딩을 보여주는 프로그래밍 예제를 몇 가지 살펴 보겠습니다.
예 1 :멤버 연산자 함수를 사용하여 단항 연산자 오버로딩.
#include using namespace std; class Distance { public: int feet; // Constructor to initialize the object's value Distance(int feet) { this->feet = feet; } //operator function to overload ++ operator to perform increment on Distance obj void operator++() { feet++; } void print(){ cout << '
Incremented Feet value: ' << feet; } }; int main() { Distance d1(9); // Use (++) unary operator ++d1; d1.print(); return 0; }
산출:
증분 된 피트 값 : 10
여기서는 연산자 ++ 함수를 사용하여 단항 증가 연산자를 오버로드했습니다. 주 함수에서이 ++ 연산자를 사용하여 Distance 클래스의 객체를 증가시킵니다.
예 2 :멤버 연산자 함수를 사용한 이항 연산자 오버로딩.
#include using namespace std; class Complex { int real, imag; public: Complex(int r = 0, int i =0) {real = r; imag = i;} //Operator function to overload binary + to add two complex numbers Complex operator + (Complex const &obj) { Complex c3; c3.real = real + obj.real; c3.imag = imag + obj.imag; return c3; } void print() { cout << real << ' + i' << imag << endl; } }; int main() { Complex c1(2, 5), c2(3, 7); cout<<'c1 = '; c1.print(); cout<<'c2 = '; c2.print(); cout<<'c3 = c1+c2 = '; Complex c3 = c1 + c2; // calls overloaded + operator c3.print(); }
산출:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
여기에서는 연산자 오버로딩을 사용하여 두 개의 복소수를 더하는 고전적인 예를 사용했습니다. 우리는 복소수를 나타내는 클래스와 복소수의 실수 부와 허수 부를 추가하는 + 연산자를 오버로드하는 연산자 함수를 정의합니다.
주 함수에서 두 개의 복잡한 개체를 선언하고 오버로드 된 + 연산자를 사용하여 추가하여 원하는 결과를 얻습니다.
아래 예에서는 friend 함수를 사용하여 두 개의 복소수를 추가하여 구현의 차이를 확인합니다.
#include using namespace std; class Complex { int real, imag; public: Complex(int r = 0, int i =0) {real = r; imag = i;} //friend function to overload binary + to add two complex numbers friend Complex operator +(Complex const &, Complex const &); void print() { cout << real << ' + i' << imag << endl; } }; Complex operator + (Complex const &c1, Complex const &c2) { Complex c3; c3.real = c1.real + c2.real; c3.imag = c1.imag + c2.imag; return c3; } int main() { Complex c1(2, 5), c2(3, 7); cout<<'c1 = '; c1.print(); cout<<'c2 = '; c2.print(); cout<<'c3 = c1+c2 = '; Complex c3 = c1 + c2; // calls overloaded + operator c3.print(); }
산출:
c1 = 2 + i5
c2 = 3 + i7
c3 = c1 + c2 = 5 + i12
프로그램의 출력이 동일하다는 것을 알 수 있습니다. 구현의 유일한 차이점은 이전 구현에서 멤버 함수 대신 + 연산자를 오버로드하기 위해 friend 함수를 사용하는 것입니다.
이항 연산자에 friend 함수를 사용하는 경우 두 피연산자를 함수에 명시 적으로 지정해야합니다. 마찬가지로, 단항 연산자가 friend 함수를 사용하여 오버로드 될 때 함수에 단일 피연산자를 제공해야합니다.
연산자 함수 외에도 다음을 작성할 수도 있습니다. 변환 연산자 한 유형에서 다른 유형으로 변환하는 데 사용됩니다. 이러한 오버로드 된 변환 연산자는 클래스의 멤버 함수 여야합니다.
예 3 :변환 연산자를 사용하는 연산자 오버로딩.
#include using namespace std; class DecFraction { int numerator, denom; public: DecFraction(int num, int denm) { numerator = num; denom = denm; } // conversion operator: converts fraction to float value and returns it operator float() const { return float(numerator) / float(denom); } }; int main() { DecFraction df(3, 5); //object of class float res_val = df; //calls conversion operator cout << 'The resultant value of given fraction (3,5)= '< 산출:
주어진 분수의 결과 값 (3,5) = 0.6
이 프로그램에서는 변환 연산자를 사용하여 주어진 분수를 부동 값으로 변환했습니다. 변환이 완료되면 변환 연산자는 결과 값을 호출자에게 반환합니다.
주 함수에서 df 객체를 res_val 변수에 할당하면 변환이 발생하고 결과가 res_val에 저장됩니다.
단일 인수로 생성자를 호출 할 수도 있습니다. 단일 인수를 사용하여 클래스에서 생성자를 호출 할 수있는 경우이를 ' 변환 건축업자 ”. 변환 생성자는 생성중인 클래스로의 암시 적 변환에 사용할 수 있습니다.
#include using namespace std; class Point { private: int x,y; public: Point(int i=0,int j=0) {x = i;y=j;} void print() { cout<<' x = '< 산출:
일반 생성자를 사용하여 생성 된 포인트
x = 20 y = 30
변환 생성자를 사용하여 생성 된 포인트
x = 10 y = 0

여기에 기본값으로 생성자를 정의하는 Point 클래스가 있습니다. 주 함수에서 우리는 x 및 y 좌표로 객체 pt를 생성합니다. 다음으로 pt에 10의 값을 할당합니다. 여기서 변환 생성자가 호출되고 x에는 10의 값이 할당되고 y에는 기본값 0이 할당됩니다.
연산자 오버로딩 규칙
연산자 오버로딩을 수행하는 동안 아래 규칙을주의해야합니다.
- C ++에서는 기존 연산자 만 오버로드 할 수 있습니다. 새로 추가 된 연산자는 오버로드 할 수 없습니다.
- 연산자가 오버로드되면 피연산자 중 하나 이상이 사용자 정의 유형인지 확인해야합니다.
- 특정 연산자를 오버로드하기 위해 friend 함수도 사용할 수 있습니다.
- 멤버 함수를 사용하여 단항 연산자를 오버로드 할 때 명시 적 인수를 사용하지 않습니다. 단항 연산자가 friend 함수를 사용하여 오버로드 될 때 하나의 명시 적 인수를 사용합니다.
- 마찬가지로 이항 연산자가 멤버 함수를 사용하여 오버로드되면 함수에 하나의 명시 적 인수를 제공해야합니다. 이항 연산자가 friend 함수를 사용하여 오버로드되면 함수는 두 개의 인수를 사용합니다.
- C ++에는 이미 오버로드 된 두 개의 연산자가 있습니다. 이들은 '='및 '&'입니다. 따라서 동일한 클래스의 객체를 복사하려면 = 연산자를 오버로드 할 필요가 없으며 직접 사용할 수 있습니다.
연산자 오버로딩의 장점
C ++의 연산자 오버로딩을 사용하면 기본 제공 형식 외에 클래스 개체를 포함하여 사용자 정의 형식으로 연산자의 기능을 확장 할 수 있습니다.
연산자 기능을 사용자 정의 유형으로 확장하면 사용자 정의 유형에 대한 다양한 작업을 수행하기 위해 복잡한 코드를 작성할 필요가 없지만 내장 유형과 마찬가지로 하나의 작업 자체에서 수행 할 수 있습니다.
결론
컴파일 시간 다형성은 주로 함수 오버로딩 및 연산자 오버로딩 측면에서 코드의 기능을 확장하는 오버로딩 기능을 제공합니다.
함수 오버로딩을 통해 이름은 같지만 매개 변수와 유형이 다른 둘 이상의 함수를 작성할 수 있습니다. 이렇게하면 코드를 간단하고 쉽게 읽을 수 있습니다. 연산자 오버로딩을 통해 연산자의 기능을 확장하여 사용자 정의 형식에 대한 기본 작업도 수행 할 수 있습니다.
다음 자습서에서는 C ++의 런타임 다형성에 대해 자세히 알아 봅니다.
추천 도서