Intro
이번 포스팅에서는 C++의 장점 중 하나인 다형성에 대해 알아보도록 하겠습니다. C++을 공부하다 보면 다형성이라는 단어를 자주 접하게 될 것입니다. 하지만 다형성...이라는 단어를 접했을 때 평소 사용하지 않아서 생소했습니다. 그래서 다형성이라는 국어사전에 나온 의미에 대해 찾아봤습니다.
다형성 : 동일종(同一種)의 생물이면서도 형태나 성질이 다양성을 보이는 상태. 암수에 의한 크기·형태·색깔 등의 차이와 꿀벌에서의 여왕벌과 일벌 같은 것(구글 국어사전 검색).
위에 다형성이라는 국어사전에서 나타내는 의미를 찾아보고 다형성에 대해 학습하니 C++에서의 다형성의 개념의 이해가 잘 갔습니다. 즉, C++에서 다형성이란 동일한 메시지에 대해 복수의 다른 응답을 하는 것입니다.
오버로드 vs 오버라이드
오버로드(overload) : 한 개의 클래스 내에 동일한 이름의 멤버 함수를 복수 정의하는 것입니다.
소스코드를 통해 오버로드에 대해 살펴보도록 하겠습니다.
#include <iostream>
using namespace std;
class Anabebe
{
public:
int func(int a);
double func(double b);
};
int Anabebe::func(int a)
{
return a*2;
}
double Anabebe::func(double b)
{
return b*3.14;
}
int main(void)
{
Anabebe obj;
int a;
double b;
a = obj.func(10);
b = obj.func(1.0);
cout << a << endl;
cout << b << endl;
}
결과
소스코드를 보면 하나의 클래스에 동일한 이름의 함수가 두개가 있습니다. 두 함수의 차이는 함수의 리턴 타입이 int, double고 함수의 인수도 int, double입니다. 이렇게 하고 main함수에서 호출을 func함수를 호출하게 되면 컴파일러가 알아서 같은 형으로 컴파일이 되기 때문에 오버로드가 실현되고 있다는 뜻입니다.
주의해야 할 점은 C++ 컴파일러는 이름과 인수로 멤버 함수를 식별하지만 반환값은 식별의 대상이 되지 않습니다. 즉, func(인수)에서 인수에 따라 식별이 된고, return타입은 고려되지 않습니다. double b = obj.func(10)이런식으로 호출을 하게 되면 b에는 20이 저장됩니다.
오버로드 활용의 두 가지 패턴
오버로드를 활용하기 위한 패턴으로는 크게 두 가지가 있습니다.
하나는 완전한 동일한 작업 내용에서 인수의 자료형만이 다른 멤버 함수를 오버로드 하는 것입니다.
sample code
class Anabebe
{
public:
int func(int a);
double func(double b);
};
int Anabebe::func(int a)
{
return a*2;
}
double Anabebe::func(double b)
{
return b*3.14;
}
또 다른 패턴은 인수의 수가 다른 동일한 이름의 멤버 함수를 정의하는 것입니다.
sample code
class Anabebe
{
public:
int func(int a);
void func(char* s, double a);
};
int Anabebe::func(int a)
{
return a*2;
}
void Anabebe::func(char* s,double a)
{
cout << s << a << endl;
}
다른 수의 인수를 가진 멤버 함수를 오버로드 할 경우에는 하나의 멤버 함수가 다른 멤버 함수를 호출하게 하면 코드를 효율적으로 설명할 수 있습니다. 호출되는 측의 멤버 함수를 수정하면 그 내용이 다른 멤버 함수에게도 반영되기 때문입니다.
오버라이드(override): 기본 클래스의 멤버 함수 처리 내용을 파생 클래스에서 재정의 하는 것을 오버라이드라고 합니다. 오버라이드는 상속한 멤버 함수의 처리 내용이 파생 클래스의 목적에 맞지 않을 경우 멤버 함수의 원형을 그대로 두고, 처리 내용을 자유롭게 재정의할 수 있다는 점에서 편리합니다. 이 구조를 연구하여 사용함으로 다형성을 실현하고 클래스를 사용하는 측의 코드를 짧고 효율적으로 설명할 수 있게 됩니다.
소스코드를 통해 확인해 보겠습니다.
#include <iostream>
using namespace std;
class Anabebe
{
public:
virtual void showdata();
};
void Anabebe::showdata()
{
cout << "Anabebe Class 호출" << endl;
}
class Anabebe2 : public Anabebe
{
public:
void showdata();
};
void Anabebe2::showdata()
{
Anabebe::showdata();
cout << "Anabebe2 Class 호출" << endl;
}
int main(void)
{
Anabebe2 obj2;
obj2.showdata();
}
결과
코드를 보면 Anabebe2에서 Anabebe클래스를 상속받아 showdata() 함수를 재정의 했습니다. 코드를 이렇게 보면 정말 아무것도 아닌 것처럼 보이는데 이걸 긴 코드에서 테크닉 적으로 사용하면 코드를 보다 짧고 효율적으로 설명할 수 있습니다.
마무리
이번 포스팅에서 C++에서 다형성을 실현하기 위한 오버로드와 오버라이드에 대해 알아봤습니다. 오버라이드에서 순수 가상 함수와 추상 클래스에 대한 내용이 빠졌는데.. 이걸 추가하다 보면 너무 길어질 것 같아서 다음번에 따로 포스팅을 하도록 하겠습니다.
마지막으로 오버로드, 오버라이드 두 개의 차이를 정리하자면 오버로드는 한 개의 클래스 내에 동일한 이름의 멤버 함수를 복수 정의하는 것이고, 오버라이드는 기본 클래스의 멤버 함수 처리 내용을 파생 클래스에서 재정의 하는 것을 오버라이드라고 합니다.
오버로드, 오버라이드 C++에 다형성을 실현하기 위한 기능이지만, 프로그래머가 코드를 구현할 때 꼭 사용해야 하는 테크닉은 아닙니다. 하지만 두 개념을 이해하고 프로그래밍을 하면 보다 효율적이고 재미를 느낄 수 있을 것입니다.
그럼 이만 포스팅 마치겠습니다. 감사합니다.
'[C/C++/MFC]' 카테고리의 다른 글
시리얼 통신(Serial Communication) C++ (0) | 2023.07.19 |
---|---|
[C++ Visual studio 2019 & Google Test 연동 방법(Unit test)] (2) | 2021.07.17 |
[C++ 캡슐화] (0) | 2021.07.04 |
[C++ 객체 지향 프로그래밍 특징(상속, 캡슐화, 다형성] (0) | 2021.05.09 |
[C++ 절차지향 프로그래밍 vs 객체지향 프로그래밍] (0) | 2021.05.08 |