본문 바로가기

Computer Science&Engineering/C\C++

[C++] 함수 오버로딩 vs 오버라이딩

# 함수 오버로딩(overloading)이란

 

서로 다른 함수에 대하여 같은 이름을 사용하는 기능입니다. 함수의 이름은 같지만 함수 선언에 사용된 매개변수의 타입이나 갯수가 다를 때, 함수 오버로딩이 가능합니다. 이 때 리턴 타입은 서로 다른 함수에 포함되지 않습니다.

 

아래 코드에서 square 라는 이름의 함수가 오버로딩 되었습니다.

 

int square(int x) { return x * x; }
double square(double x) { return x * x; }

int main() {
  cout << square(2) << "\n";
  cout << square(2.2) << "\n";

  return 0;
}

 

함수 오버로딩의 원리는 컴파일러가 '함수 이름'과 '매개변수 정보'를 가지고 함수이름을 헝클어뜨리는 name mangling 입니다. 

 

위의 소스코드를 VS2019에서 컴파일 한 후, 오브젝트 파일을 보면 아래와 같이 함수가 정의되어있습니다. 이름은 같은 square 이지만, 컴파일러가 매개변수와 함께 헝클어뜨린 함수이름 두 개를 볼 수 있습니다.

 

PUBLIC	?square@@YAHH@Z					; square
PUBLIC	?square@@YANN@Z					; square

 

square(2)를 호출하면 square(int x) 가 호출될까요? square(double x) 가 호출될까요? 

 

직관적으로 square(int)라는 것을 떠올릴 수 있습니다.

 

컴파일러는 오버로딩된 함수를 호출할 때 아래의 순서로 호출하게 됩니다. 

 

1. 완전 일치: 완벽하게 일치된 타입을 사용
2. 승격: 데이터의 손실이 없는 쪽으로 변환 후, 사용
3. 표준 변환: 데이터의 손실이 있더라도 암시적 변환 후 사용
4. 사용자 정의 변환 -> 연산자 오버로딩
5. 가변 인자 (...)

 

 

# 함수 오버라이딩(overriding)이란

 

서로 다른 클래스가 상속 관계에 있을 때, 자식 클래스가 부모 클래스 함수를 재정의하는 것을 함수 오버라이딩이라고 합니다. 

 

부모의 함수를 재정의하는 것이므로, 부모 함수의 프로토타입과 완벽하게 동일해야 합니다.

 

함수 오버라이딩은 자식의 함수가 부모의 함수를 가리는 기능입니다. 

 

아래 코드에서 Cat 클래스는 Animal 클래스를 상속받았습니다. Cat 객체 c1 에서 walk함수를 호출하면 부모클래스의 walk()가 호출됩니다.

 

#include <iostream>
using namespace std;

class Animal
{
public:
  void walk() { cout << "동물이 걷는다. \n"; }
};

class Cat : public Animal
{};

int main() {
	Animal a1;
	a1.walk();
	
	Cat c1;
	c1.walk();
}

 

>> 결과

 

동물이 걷는다.
동물이 걷는다.

 

 

이 때 자식 클래스인 Cat에서 walk 함수를 오버라이딩 합니다. 자식객체에서 walk 함수를 호출 할 때, 더이상 부모 클래스의 walk가 아닌, 자식 클래스의 walk가 호출됩니다.

 

#include <iostream>
using namespace std;

class Animal
{
public:
  void walk() { cout << "동물이 걷는다. \n"; }
};

class Cat : public Animal
{
// 함수 오버라이딩
public:
  void walk() { cout << "고양이가 걷는다.\n";  }
};

int main() {
	Animal a1;
	a1.walk();
	
	Cat c1;
	c1.walk();
}

 

>> 결과 

 

동물이 걷는다.
고양이가 걷는다.

 

 

오버로딩과 오버라이딩. 비슷해서 헷갈리는 단어를 정리해보았습니다..

반응형