본문 바로가기

복습/C++

[C++] 복습일지 part 2 - 2 #오버로딩(Overloading)과 오버라이딩(Overriding)

# 상속 (Inheritance)

# 오버로딩(Overloading)과 오버라이딩(Overriding)

# 가상함수, 순수가상함수 (Virtual Function, Pure Virtual Function)

# 멤버이니셜라이저 (Memeber Initializer)


이번시간에는 

오버로딩과 오버라이딩에 대해 알아보도록할게요


스타크래프트 '오버로드' 아시나요?

네 그 오버로드입니다.



#오버로딩 (Overloading)

단어의 뜻을 한번 보겠습니다



감이 오시나요?


오버로딩(Overloading)

 - 메서드의 이름이 같고

 - 인자의 자료형이 다르거나

 - 인자의 개수가 다르거나


여기 메서드가있습니다.


    void add()
    {
        std::cout << "add()" << std::endl;
    }
    void add(int a)
    {
        std::cout << "add(int a)" << std::endl;
    }
    void add(int a, int b)
    {
        std::cout << "add(int a, int b)" << std::endl;
    }
    void add(double a, int b)
    {
        std::cout << "add(double a, int b)" << std::endl;
    }
    void add(double a, double b)
    {
        std::cout << "add(double a, double b)" << std::endl;
    }

add(4.4, 5)를 호출하면
add(double a, int  b)가 출력

add(4, 4)를 호출하면
add(int a, int b)가 출력

add(4)를 호출하면
add(int a)가 출력

이처럼 메서드의 이름은 같고
자료형이 다르거나 인자의 개수가 다르거나
(자료형이 다르다) || (인자의 개수가 다르다)

조건이 성립한다면 오버로딩입니다.
말그대로 '초과적재' 입니다.

만약 오버로딩이 없다면 
add1(int a)
add2(int a, int b)
add3(double a, int a)
add4(double a, double b)
...
...
등등 
동일한 일을 하지만 ( add()함수가 수를 더하는 기능이라는 가정)
인자의 개수와 타입에따라 전부 다르게 사용해야 할 것입니다.

오버로딩을 사용함으로써 얻는 이득이 무엇이냐?

1. 메서드의 이름을 절약 할 수 있습니다. 저는 항상 이름짓는게 제일 힘든데 이런거까지 고민해야한다면 최악입니다.
2. 외워야 할 이름이 적어집니다.

오버로딩은 함수를 호출 할 때 인자의 타입에 맞게 호출이 됩니다.
옷가게에서 후드를 고를 때 자신의 사이즈에 맞게 사는것처럼 말이죠 제가 후드를 좋아합니다

정리하자면

[오버로딩]
 메서드의 이름이 같고, 인자의 타입과 개수가 다르다면, 중복해서 선언이 가능하다.

(단, return값이 다르고 인자의 타입과 개수가 같으면 오버로딩이 되지 않는다.)
ex)
int add(){}
void add(){}
선언 불가.








# 오버라이딩 (Overriding)


간혹가다 오버로딩과 오버라이딩을 헷갈리는데요


오버라이딩이란

부모클래스에서 쓴 함수를 자식클래스에서 '재정의' 한다는것입니다.



class A
{
public:
    void function()
    {
        std::cout << "A" << std::endl;
    }
};
class B : public A
{
public:
    void function()
    {
        std::cout << "B" << std::endl;
    }
};

int main() {
    A a;
    B b;
    a.function();
    b.function();
    
    return 0;
}



다음의 출력값은 어떻게 될까요?


A클래스에도 function() 

B클래스에도 function()


둘다 있습니다. 


B클래스에서는 A의 function()을 오버라이딩(재정의) 한 것이죠

그래서 출력값이 위 그림과 같이 나옵니다.

주의할점은, 오버라이딩은 오버로딩과 다르게 '재정의'하는것이기 때문에 이름, 리턴타입, 인자의 타입,개수 가 완전히 같아야 한다는 점입니다.


예를들어


class Animal
{
public:
    void sound()
    {
        std::cout << "멍멍" << std::endl;
    }
};

class Dog : public Animal
{

};
class Cat : public Animal
{
public:
    void sound()
    {
        std::cout << "야옹" << std::endl;
    }
};

int main() {
    Dog d;
    Cat c;
    
    d.sound();
    c.sound();
    
    return 0;
}


모든 동물들이 소리를 "멍멍" 낼까요?

아닙니다

고양이는 "야옹" 을 하고싶습니다. 그렇다면

sound()메서드를 Cat 클래스에서 오버라이딩(재정의) 하면 됩니다.

간단하죠?



[오버라이딩]
자식클래스에서 부모클래스의 함수이름을 '재정의' 하는것. 함수의 이름, 리턴타입, 인자의 타입, 개수가 부모클래스의 함수와 완전히 동일할 때 오버라이딩이 가능