C++ 예제를 사용한 다형성

다형성이란 무엇입니까? C++?

In C++, 다형성은 멤버 함수를 호출/호출하는 개체에 따라 다르게 동작하도록 만듭니다. 다형성(Polymorphism)은 다양한 형태를 갖는다는 뜻을 지닌 그리스어이다. 상속을 통해 관련된 클래스의 계층 구조가 있을 때 발생합니다.

예를 들어 makeSound() 함수가 있다고 가정해 보겠습니다. 고양이가 이 함수를 호출하면 야옹 소리가 납니다. 소가 동일한 기능을 호출하면 울음소리가 납니다.

다형성 C++

하나의 기능이 있지만 상황에 따라 다르게 작동합니다. 함수에는 다양한 형태가 있습니다. 따라서 우리는 다형성을 달성했습니다.

다형성의 유형

C++ 두 가지 유형의 다형성을 지원합니다.

  • 컴파일 타임 다형성 및
  • 런타임 다형성.

다형성의 유형

컴파일 시간 다형성

인수의 수와 유형을 일치시켜 오버로드된 함수를 호출합니다. 정보는 컴파일 타임 동안 존재합니다. 이는 다음을 의미합니다. C++ 컴파일러는 컴파일 타임에 올바른 함수를 선택합니다.

컴파일 타임 다형성은 함수 오버로딩과 연산자 오버로딩을 통해 달성됩니다.

함수 오버로딩

함수 오버로드는 이름은 비슷하지만 인수가 다른 함수가 많을 때 발생합니다. 인수는 숫자나 유형에 따라 다를 수 있습니다.

예제 1

#include <iostream> 
using namespace std;

void test(int i) {
	cout << " The int is " << i << endl;
}
void test(double  f) {
	cout << " The float is " << f << endl;
}
void test(char const *ch) {
	cout << " The char* is " << ch << endl;
}

int main() {
	test(5);
	test(5.5);
	test("five");
	return 0;
}

출력:

함수 오버로딩

다음은 코드의 스크린샷입니다.

함수 오버로딩

코드 설명 :

  1. iostream 헤더 파일을 코드에 포함시킵니다. 우리는 그 기능을 사용할 수 있을 것입니다.
  2. 코드에 std 네임스페이스를 포함합니다. 우리는 그것을 호출하지 않고도 그 클래스를 사용할 수 있을 것입니다.
  3. 정수 매개변수 i를 사용하는 test라는 함수를 만듭니다. {는 함수 테스트 본문의 시작을 표시합니다.
  4. 위의 기능 테스트가 호출/호출되면 실행될 명령문입니다.
  5. 위의 기능 테스트 본문을 마칩니다.
  6. float 매개변수 f를 사용하는 test라는 함수를 만듭니다. {는 함수 테스트 본문의 시작을 표시합니다.
  7. 위의 기능 테스트가 호출/호출되면 실행될 명령문입니다.
  8. 위 기능 테스트 본문을 마칩니다.
  9. 문자 매개 변수 ch를 사용하는 test라는 함수를 만듭니다. {는 함수 테스트 본문의 시작을 표시합니다.
  10. 위의 기능 테스트가 호출/호출되면 실행될 명령문입니다.
  11. 위 기능 테스트 본문을 마칩니다.
  12. main() 함수를 호출합니다. {는 함수 본문의 시작을 표시합니다.
  13. test 함수를 호출하고 5를 인수 값으로 전달합니다. 이는 정수 인수를 허용하는 테스트 함수, 즉 첫 번째 테스트 함수를 호출합니다.
  14. test 함수를 호출하고 5.5를 인수 값으로 전달합니다. 이는 float 인수를 허용하는 테스트 함수, 즉 두 번째 테스트 함수를 호출합니다.
  15. test 함수를 호출하고 XNUMX를 인수 값으로 전달합니다. 그러면 문자 인수를 허용하는 테스트 함수, 즉 세 번째 테스트 함수가 호출됩니다.
  16. 프로그램이 성공적으로 실행되면 값을 반환해야 합니다.
  17. main() 함수 본문의 끝입니다.

이름은 같지만 인수 유형이 다른 세 가지 함수가 있습니다. 우리는 다형성을 달성했습니다.

Opera토르 과부하

In Opera오버로딩을 통해 우리는 a에 대한 새로운 의미를 정의합니다. C++ 연산자입니다. 또한 연산자의 작동 방식도 변경합니다. 예를 들어, 두 문자열을 연결하기 위해 + 연산자를 정의할 수 있습니다. 숫자 값을 더하는 덧셈 연산자로 알고 있습니다. 정의에 따라 정수 사이에 놓으면 더합니다. 문자열 사이에 놓으면 연결합니다.

예제 2

#include<iostream> 
using namespace std;

class ComplexNum {
private:
	int real, over;
public:
	ComplexNum(int rl = 0, int ov = 0) {
		real = rl;   
		over = ov; 
	}

	ComplexNum operator + (ComplexNum const &obj) {
		ComplexNum result;
		result.real = real + obj.real;
		result.over = over + obj.over;
		return result;
	}
	void print() { 
		cout << real << " + i" << over << endl; 
	}
};
int main()
{
	ComplexNum c1(10, 2), c2(3, 7);
	ComplexNum c3 = c1+c2;
	c3.print();
}

출력:

Opera토르 과부하

다음은 코드의 스크린샷입니다.

Opera토르 과부하

Opera토르 과부하

코드 설명 :

  1. 해당 기능을 사용하려면 iostream 헤더 파일을 프로그램에 포함시킵니다.
  2. 클래스를 호출하지 않고 사용하려면 std 네임스페이스를 프로그램에 포함시킵니다.
  3. ComplexNum이라는 이름의 클래스를 만듭니다. {는 클래스 본문의 시작을 표시합니다.
  4. 변수를 비공개로 표시하려면 비공개 액세스 한정자를 사용하세요. 즉, 해당 변수는 클래스 내에서만 액세스할 수 있습니다.
  5. 실수와 초과라는 두 개의 정수 변수를 정의합니다.
  6. public 액세스 한정자를 사용하여 생성자를 public으로 표시합니다. 즉, 외부에서도 액세스할 수 있습니다. 수업.
  7. 클래스 생성자를 만들고 변수를 초기화합니다.
  8. real 변수의 값을 초기화합니다.
  9. 변수의 값을 초기화합니다.
  10. 생성자 본문의 끝입니다.
  11. + 연산자의 의미를 재정의해야 합니다.
  12. ComplexNum 유형의 result 데이터 유형을 생성합니다.
  13. 복소수에는 + 연산자를 사용합니다. 이 줄은 숫자의 실수 부분을 다른 숫자의 실수 부분에 더합니다.
  14. 복소수에는 + 연산자를 사용합니다. 이 줄은 숫자의 허수부를 다른 숫자의 허수부에 더합니다.
  15. 프로그램은 성공적으로 실행되면 변수 결과 값을 반환합니다.
  16. + 연산자의 새로운 의미, 즉 오버로딩의 정의가 끝났습니다.
  17. print() 메서드를 호출합니다.
  18. 더한 후 새로운 복소수를 콘솔에 인쇄합니다.
  19. print() 함수 본문의 끝입니다.
  20. ComplexNum 클래스 본문의 끝.
  21. main() 함수를 호출합니다.
  22. 더할 실수와 복소수 부분의 값을 모두 전달합니다. c1의 첫 번째 부분은 c2의 첫 번째 부분, 즉 10+3에 더해집니다. c1의 두 번째 부분은 c의 두 번째 부분, 즉 2+7에 더해집니다.
  23. 오버로드된 + 연산자를 사용하여 연산을 수행하고 결과를 변수 c3에 저장합니다.
  24. 콘솔에 변수 c3의 값을 인쇄합니다.
  25. main() 함수 본문의 끝입니다.

런타임 다형성

이는 컴파일 시간이 아닌 런타임 중에 객체의 메서드가 호출/호출될 때 발생합니다. 런타임 다형성은 함수 재정의를 통해 달성됩니다. 호출/호출될 함수는 런타임 중에 설정됩니다.

함수 재정의

함수 재정의는 기본 클래스의 함수에 파생 클래스의 새로운 정의가 제공될 때 발생합니다. 이때 기본 기능이 재정의되었다고 말할 수 있습니다.

예 :

#include <iostream>
using namespace std;
class Mammal {

public:
	void eat() {

		cout << "Mammals eat...";
	}

};

class Cow: public Mammal {

public:
	void eat() {

		cout << "Cows eat grass...";
	}
};
int main(void) {

	Cow c = Cow();

	c.eat();

	return 0;

}

출력:

함수 재정의

다음은 코드의 스크린샷입니다.

함수 재정의

코드 설명 :

  1. 해당 기능을 사용하려면 iostream 헤더 파일을 프로그램으로 가져옵니다.
  2. 클래스를 호출하지 않고 사용하려면 std 네임스페이스를 프로그램에 포함시킵니다.
  3. Mammal이라는 클래스를 만듭니다. {는 클래스 본문의 시작을 표시합니다.
  4. 공개 액세스 수정자를 사용하여 생성하려는 함수를 공개적으로 액세스할 수 있도록 설정합니다. 이 클래스 외부에서 액세스할 수 있습니다.
  5. eat이라는 공개 함수를 만듭니다. {는 함수 본문의 시작을 표시합니다.
  6. eat() 함수가 호출될 때 cout 함수에 추가된 명령문을 인쇄합니다.
  7. eat() 함수 본문의 끝입니다.
  8. 포유류 클래스의 몸체 끝.
  9. Mammal 클래스를 상속하는 Cow라는 클래스를 만듭니다. Cow는 파생 클래스이고 Mammal은 기본 클래스입니다. {는 이 클래스의 시작을 표시합니다.
  10. 공개 액세스 수정자를 사용하여 생성하려는 함수를 공개적으로 액세스할 수 있도록 표시합니다. 이 클래스 외부에서 액세스할 수 있습니다.
  11. 기본 클래스에 정의된 eat() 함수를 재정의합니다. {는 함수 본문의 시작을 표시합니다.
  12. 이 함수가 호출될 때 콘솔에 인쇄할 명령문입니다.
  13. eat() 함수 본문의 끝입니다.
  14. Cow 클래스 본체의 끝입니다.
  15. main() 함수를 호출합니다. {는 이 함수 본문의 시작을 표시합니다.
  16. Cow 클래스의 인스턴스를 생성하고 이름을 지정합니다. c.
  17. Cow 클래스에 정의된 eat() 함수를 호출합니다.
  18. 프로그램은 성공적으로 완료되면 값을 반환해야 합니다.
  19. main() 함수의 끝입니다.

C++ 가상 기능

가상 함수는 런타임 다형성을 구현하는 또 다른 방법입니다. C++. 기본 클래스에서 정의되고 파생 클래스에서 재정의되는 특수 함수입니다. 가상 함수를 선언하려면 virtual 키워드를 사용해야 합니다. 키워드는 기본 클래스에서 함수 선언 앞에 와야 합니다.

가상 함수 클래스가 상속되면 가상 클래스는 필요에 맞게 가상 함수를 재정의합니다. 예를 들어:

#include <iostream>  
using namespace std;
class ClassA {
		public:
		virtual void show() {
			cout << "The show() function in base class invoked..." << endl;
		}
	};
	class ClassB :public ClassA {
	public:
		void show() 	{
			cout << "The show() function in derived class invoked...";
		}
	};
	int main() {
		ClassA* a;   
		ClassB b;
		a = &b;
		a->show();      
	}

출력:

C++ 가상 기능

다음은 코드의 스크린샷입니다.

C++ 가상 기능

코드 설명 :

  1. 해당 기능을 사용하려면 코드에 iostream 헤더 파일을 포함하세요.
  2. 클래스를 호출하지 않고 사용하려면 코드에 std 네임스페이스를 포함하세요.
  3. ClassA라는 클래스를 만듭니다.
  4. 클래스 멤버를 공개적으로 액세스할 수 있도록 표시하려면 public 액세스 한정자를 사용하세요.
  5. show()라는 가상 함수를 만듭니다. 공개적인 기능이 될 것입니다.
  6. show()가 호출될 때 인쇄할 텍스트입니다. 엔드는 C++ 키워드는 끝줄을 의미합니다. 마우스 커서를 다음 줄로 이동시킵니다.
  7. 가상 함수 show()의 본문 끝입니다.
  8. ClassA 클래스 본문의 끝입니다.
  9. ClassA 클래스를 상속하는 ClassB라는 새 클래스를 만듭니다. ClassA는 기본 클래스가 되고 ClassB는 파생 클래스가 됩니다.
  10. 클래스 멤버를 공개적으로 액세스할 수 있도록 표시하려면 public 액세스 한정자를 사용하세요.
  11. 기본 클래스에서 파생된 가상 함수 show()를 재정의합니다.
  12. 파생 클래스에 정의된 show() 함수가 호출될 때 콘솔에 인쇄할 텍스트입니다.
  13. show() 함수 본문의 끝입니다.
  14. 파생 클래스 ClassB의 본문 끝입니다.
  15. main() 함수를 호출합니다. 프로그램 논리는 해당 본문 내에 추가되어야 합니다.
  16. a라는 포인터 변수를 만듭니다. ClassA라는 클래스를 가리킵니다.
  17. ClassB라는 클래스의 인스턴스를 만듭니다. 인스턴스 이름은 b로 지정됩니다.
  18. 변수 a에 주소 b에 저장된 값을 할당합니다.
  19. 파생 클래스에 정의된 show() 함수를 호출합니다. 후기 바인딩이 구현되었습니다.
  20. main() 함수 본문의 끝입니다.

컴파일 타임 다형성 대. 런타임 다형성

둘 사이의 주요 차이점은 다음과 같습니다.

컴파일 타임 다형성 런타임 다형성
초기 바인딩 또는 정적 다형성이라고도 합니다. 후기/동적 바인딩 또는 동적 다형성이라고도 합니다.
메소드는 컴파일 시간 동안 호출/호출됩니다. 런타임 중에 메서드가 호출/호출됩니다.
함수 오버로딩 및 연산자 오버로딩을 통해 구현됨 메서드 재정의 및 가상 함수를 통해 구현됨
예, 메소드 오버로딩. 많은 메서드가 비슷한 이름을 가질 수 있지만 인수의 수나 유형이 다를 수 있습니다. 예, 메서드 재정의. 많은 메서드가 비슷한 이름과 동일한 프로토타입을 가질 수 있습니다.
컴파일 시간 동안 메소드 검색이 수행되므로 실행 속도가 빨라집니다. 메소드 발견자가 런타임 중에 수행되므로 실행 속도가 느려집니다.
Less 컴파일 시간 동안 모든 것이 알려지기 때문에 문제 해결을 위한 유연성이 제공됩니다. 런타임 중에 메서드가 발견되므로 복잡한 문제를 해결하는 데 많은 유연성이 제공됩니다.

요약

  • 다형성은 다양한 형태를 갖는다는 뜻이다.
  • 상속을 통해 관련된 클래스의 계층 구조가 있을 때 발생합니다.
  • 다형성을 사용하면 함수를 호출/호출하는 개체에 따라 함수가 다르게 동작할 수 있습니다.
  • 컴파일 타임 다형성에서는 호출할 함수가 컴파일 타임에 설정됩니다.
  • 런타임 다형성에서는 호출될 함수가 런타임 중에 설정됩니다.
  • 컴파일 타임 다형성은 함수 오버로딩과 연산자 오버로딩을 통해 결정됩니다.
  • 함수 오버로딩에는 이름은 비슷하지만 인수가 다른 함수가 많이 있습니다.
  • 매개변수의 수나 유형이 다를 수 있습니다.
  • 연산자 오버로딩에서는 새로운 의미가 정의됩니다. C++ 운영자.
  • 런타임 다형성은 함수 재정의를 통해 달성됩니다.
  • 함수 재정의에서 파생 클래스는 기본 클래스에 정의된 함수에 새로운 정의를 제공합니다.