프로그래밍 언어/C++
오버라이딩(Overriding) vs 오버로딩(Overloading) 정리
로안님
2025. 1. 24. 20:47
C++의 **오버라이딩(Overriding)**과 **오버로딩(Overloading)**은 객체지향 프로그래밍에서 자주 사용되는 개념입니다. 게임 개발에서 효율적인 코드 작성과 다형성(Polymorphism)을 활용하는 데 중요한 역할을 합니다. 오늘은 이 두 가지의 차이와 사용법을 정리해보겠습니다!
오버라이딩(Overriding)
개념
오버라이딩은 상속 관계에서 **부모 클래스의 가상 함수(Virtual Function)**를 **자식 클래스에서 재정의(Override)**하는 것을 말합니다.
이를 통해 기본 클래스의 포인터나 참조로 자식 클래스의 구현을 호출할 수 있습니다.
특징
- 기본 클래스의 가상 함수만 재정의 가능.
- 자식 클래스에서 재정의하지 않으면 기본 클래스의 구현이 호출됩니다.
- 런타임 다형성을 구현하여, 실행 중에 호출할 함수가 결정됩니다.
코드 예제: 오버라이딩
기본 클래스와 자식 클래스
#include <iostream>
using namespace std;
class Base {
public:
virtual void Display() { // 가상 함수
cout << "Base Display" << endl;
}
};
class Derived : public Base {
public:
void Display() override { // 오버라이딩
cout << "Derived Display" << endl;
}
};
호출 예제
int main() {
Base* obj = new Derived(); // 기본 클래스 포인터로 자식 객체 참조
obj->Display(); // Derived Display 출력
delete obj;
return 0;
}
오버로딩(Overloading)
개념
오버로딩은 같은 이름의 함수를 매개변수의 개수나 타입을 다르게 정의하는 것을 말합니다.
컴파일 타임에 호출할 함수가 결정되며, 같은 이름으로 다양한 동작을 구현할 수 있습니다.
특징
- 같은 클래스 내에서 정의되며, 상속 관계는 필요하지 않습니다.
- 함수 이름은 같지만, 매개변수의 타입, 개수, 순서가 달라야 합니다.
- 반환 타입만 다른 경우는 오버로딩이 불가능.
코드 예제: 오버로딩
여러 버전의 함수 정의
#include <iostream>
using namespace std;
class Example {
public:
void Print(int value) { // 매개변수: int
cout << "Integer: " << value << endl;
}
void Print(double value) { // 매개변수: double
cout << "Double: " << value << endl;
}
void Print(int value1, int value2) { // 매개변수: 2개의 int
cout << "Two Integers: " << value1 << ", " << value2 << endl;
}
};
호출 예제
int main() {
Example ex;
ex.Print(10); // Integer: 10
ex.Print(3.14); // Double: 3.14
ex.Print(10, 20); // Two Integers: 10, 20
return 0;
}
오버라이딩 vs 오버로딩: 주요 차이점
특징오버라이딩(Overriding)오버로딩(Overloading)
목적 | 상속 관계에서 함수의 동작을 변경. | 같은 이름의 함수를 다양한 방식으로 호출. |
클래스 관계 | 반드시 상속 관계에 있어야 함. | 상속과 무관하게 같은 클래스 내에서 정의 가능. |
컴파일/런타임 | 런타임 다형성: 실행 중에 호출할 함수가 결정. | 컴파일 타임: 컴파일 시점에 호출할 함수 결정. |
함수 이름 | 동일해야 함. | 동일해야 함. |
매개변수 | 매개변수 목록이 동일해야 함. | 매개변수의 타입, 개수, 순서가 달라야 함. |
반환 타입 | 동일해야 함. | 반환 타입만 다르면 오버로딩 불가능. |
게임 개발에서의 활용
1. 오버라이딩: 다형성을 활용한 동작 확장
게임 개발에서 오버라이딩은 공통 인터페이스로 다양한 동작을 구현하는 데 사용됩니다.
예: 캐릭터 클래스
class Character {
public:
virtual void Attack() { // 가상 함수
cout << "Basic attack!" << endl;
}
};
class Warrior : public Character {
public:
void Attack() override {
cout << "Warrior swings a sword!" << endl;
}
};
class Mage : public Character {
public:
void Attack() override {
cout << "Mage casts a fireball!" << endl;
}
};
- 결과: Character* 포인터로 참조해도 실제 객체에 따라 적절한 공격 방식이 호출됩니다.
2. 오버로딩: 유연한 함수 호출
오버로딩은 매개변수에 따라 다른 동작을 유연하게 처리할 수 있습니다.
예: 데미지 계산
class DamageCalculator {
public:
void CalculateDamage(int baseDamage) {
cout << "Damage: " << baseDamage << endl;
}
void CalculateDamage(int baseDamage, float multiplier) {
cout << "Critical Damage: " << baseDamage * multiplier << endl;
}
};
- 결과: 매개변수의 타입과 개수에 따라 다양한 데미지 계산 방식을 호출할 수 있습니다.
결론
오버라이딩(Overriding)
- 상속 관계에서 부모 클래스의 가상 함수를 재정의(Override).
- 런타임 다형성을 지원하며, 실행 시점에 호출할 함수를 결정.
오버로딩(Overloading)
- 같은 클래스에서 매개변수를 다르게 하여 함수 이름을 재사용.
- 컴파일 시점에 호출할 함수가 결정되며, 유연한 함수 호출을 지원.
게임 개발에서의 요약
- 오버라이딩: 공통 인터페이스를 기반으로 객체별로 다른 동작을 구현하고 싶을 때.
- 오버로딩: 동일한 이름의 함수로 다양한 매개변수 조합을 처리하고 싶을 때.