다형성

최정훈·2024년 10월 14일

객체지향에서 다형성은 여러가지 형태를 가질 수 있는 능력을 의미한다. C++에서 다형성은 상속, 오버로딩, 오버라이딩, 템플릿에 의한 다형성 등으로 구현된다.

다형성을 이용하면 코드가 간결해지고, 가독성이 향상되고 코드의 유연성이 증가한다.

상속을 통한 다형성

#include <iostream>

using namespace std;

class Animal{
    public:
    virtual void Bark(){
        cout << "Ani";
    }
};

class Dog : public Animal{
    public:
    void Bark() override{
        cout << "Dog";
    }
};

class Cat : public Animal{
    public:
    void Bark() override{
        cout << "Cat";
    }
};

int main() {
    Animal* dog = new Dog();
    Animal* cat = new Cat();
    dog->Bark();   // 출력: Dog
    cat->Bark();   // 출력: Cat

    return 0;
}

이는 가상함수 vitrual과 상속을 통해서 다형성을 구현한 것이다. Animal이라는 부모 클래스로부터 Dog와 Cat가 파생되었다.

이들은 Bark() 라는 가상함수를 재정의하여 자신만의 울음소리를 출력한다. 이렇게하면 Animal클래스의 포인터를 통해 Dog와 Cat클래스의 Bark() 를 호출할 수 있다.

오버로딩, 오버라이딩을 통한 다형성

아마도 가장 많이 접할 수 있는 형태의 다형성일 것이다.

오버로딩

같은 이름의 함수를 여러 개 정의하는 것을 의미한다. 각각의 함수들은 매개변수의 타입이나 갯수가 다르게 설정된다. 이때, 매서드의 이름이 같아야하고, 파라미터의 갯수는 달라야 한다.

오버라이딩

부모 클래스의 매서드를 자식 클래스에서 재정의하는 것이다. 이때, 부모 클래스에 오버라이드하고자 하는 매서드가 있어야하며, 매서드의 이름이 같아야하고, 리턴형까지 같아야한다.


템플릿을 통한 다형성

일반화 프로그래밍을 가능하게 만들어주는 것(C#의 제네릭). 이를 사용하면 여러 타입에 대응되는 하나의 매서드나 객체를 만들 수 있다.

int add(int x, int y) {
    return x + y;
}

double add(double x, double y) {
    return x + y;
}

위의 예시는 두 매개변수를 더한 값을 리턴해주는 매서드이다. 바로 위에서 언급한 오버로딩의 한 예시이다. 하지만, 각각의 자료형에 따라서 새로운 매서드가 필요하다는 단점이 있다.

template <typename T>
T add(T x, T y){
  return x + y;
}

int intAdd = add<int>(1, 3);
float floatAdd = add<float>(1.1, 1.3);

위와 같이 템플릿을 사용한다면, 코드 하나로 모든 자료형에 대해서 유연하게 적용할 수 있다.

이는 template 이라는 예약어로 정의한다.typename을 T라고 부르고, 아래에 위치한 함수를 템플릿으로 정의하겠다는 의미이다. 이때, T는 일반적으로 사용되는 문자이며, 다른 문자를 사용해도 무방하다.

💡 템플릿 타입은 컴파일러가 컴파일 시에 사용되고자 하는 타입으로 클래스 코드를 생성해 낸다.

만약 위의 예시처럼 intfloat 형식으로 사용한다면 컴파일 시에 컴파일러가 int, float 타입의 클래스를 만들어낸다.


다형성의 장점 및 필요성

  • 코드의 재사용성을 높일 수 있다. 같은 이름의 함수나 매서드를 다양한 방식으로 사용할 수 있다.
  • 코드의 유연성을 높일 수 있다. 프로그램의 수정이나 확장을 쉽게 할 수 있다.
  • 코드의 가독성을 높일 수 있다. 같은 이름의 함수가 다양한 동작을 하는 것만 이해하면, 코드가 어떤 동작을 할지 예상이 가능하다.

다형성의 단점

  • 성능저하 실행시점에 적절한 매서드를 결정해야 함으로, 약간의 성능저하가 발생할 수 있다. 하지만, 이는 무시할 수 있는 수준이다.
  • 설계 복잡성 다형성을 제대로 설계하기 위해서는 신중한 설계가 필요하다. 계층 구조를 잘못 설계하면 오히려 복잡하기만 한 코드가 생성되고 유지보수도 어려워진다.
profile
게임개발자(희망)의 공부일지

0개의 댓글