Overloading 과 Overriding 의 차이점
본문 바로가기
Computer Science/객체 지향 프로그래밍

Overloading 과 Overriding 의 차이점

by 조훈이 2021. 7. 28.

Overloading 과 Overriding 의 차이점

오버로딩과 오버라이딩의 차이점


  Overloading 

  오버로딩(Overloading) 이란, 같은 이름을 갖는 함수나 연산자를 정의하는 것을 의미한다. 먼저, 함수의 오버로딩(Functional Overloading)두 개 이상의 함수가 같은 이름을 가졌지만, 서로 다른 매개변수(Parameter) 리스트를 가질 때 발생한다. 아래와 같은 예시가 있다.

 

#include <iostream>

using namespace std;

int add(int A, int B, int C) {
	return A + B + C;
}

int add(int A, int B) {
	return A + B;
}

int main() {
	int num1 = 2;
	int num2 = 4;
	int num3 = 17;

	cout << " num1 + num2 = " << add(num1, num2) << '\n';
	cout << " num1 + num2 + num3 = " << add(num1, num2, num3) << '\n';
}

실행 결과

  함수의 오버로딩을 활용한 쉬운 예시 이다. add(...) 함수가 사용이 되면 컴파일러가 실제 매개변수의 타입을 고려하여 실제 매개변수와 가장 가까운 적절한 시그니쳐를 갖는 함수를 호출하게 된다.

  그 결과, 2개의 정수를 더하는 경우와 3개의 정수를 더하는 경우 모두 오버로딩된 add(...) 함수를 사용하여 결과를 출력 할 수 있다.

 

  C++ 에서는 연산자의 오버로딩(Operator overloading) 이 가능하며 이는 '+', '-', '==' 와 같은 연산자의 오버로딩을 허용하는 것 이다. 아래와 같은 예시가 있다.

 

#include <iostream>
#include <string>

using namespace std;

class Person{
public:
	string name;
	short age;

	bool operator < (const Person& A) {
		return this->age < A.age;
	} // Class 내부에 선언 및 정의
};

bool operator == (const Person& A, const Person& B) {
	return A.age == B.age;
} // Class 외부에 선언 및 정의

int main() {
	Person* team_A = new Person[2];

	team_A[0] = { "Jason", 21 };
	team_A[1] = { "Melissa", 28 };

	if (team_A[0] < team_A[1]) cout << " " << team_A[1].name << " is order than " << team_A[0].name << '\n';
	else if (team_A[1] < team_A[0]) cout << " " << team_A[0].name << " is order than " << team_A[1].name << '\n';
	else cout << " Same age" << '\n';
}

실행 결과

  Person class 객체의 크기 비교 및 동등성을 검사하는 연산자 오버로딩을 하였다. '<' Operator 는 Class 내부에, '==' Operator 는 Class 외부에 선언 및 정의를 하였다. 이 둘은 성능 차이는 없다고 한다. (혹시 있으면 꼭 말씀 해 주세요.. )

  Person class 객체간의 비교 및 동등성 검사는 객체의 age 를 가지고 검사를 하였다. Melissa 의 나이는 28살으로 초기화를 하였으므로 21살인 Jason 보다 많다. 따라서 , "Melissa is order than Jason" 이라는 문장이 출력이 된 것을 확인할 수 있다.


  Overriding

  오버라이딩(Overriding)은 Class 의 상속에서 사용이 된다. 상속이 된 두 Class 가 있다고 하자. 이 때 하위 Class 는 상위 Class 의 메소드를 사용할 수 있다. 하지만 이렇게 되는 경우, 하위 Class 에서 의도와 다른 경우가 발생할 수 있다. 그래서, 하위 Class 에서 상위 Class 의 메소드와 동일한 형식의 메소드를 정의해야 할 때가 있다. 이 때 오버라이딩(Overriding) 이 사용이 된다.

 

#include <iostream>

using namespace std;

class Parent {
public:
	void print() {
		cout << " This is Parent class" << '\n';
	}
	virtual void print2() {
		cout << " This is Parent class" << '\n';
	}
};

class Child : public Parent {
public:
	void print() {
		cout << " This is Child Class" << '\n';
	}
	virtual void print2() {
		cout << " This is Child Class" << '\n';
	}
};

int main() {
	Child C;
	C.print(); // 첫 번째 출력

	Parent P;
	P.print(); // 두 번째 출력

	Child* p_C = new Child;
	p_C->print(); // 세 번째 출력

	Parent* p_P = p_C;
	p_P->print(); // 네 번째 출력
	p_P->print2(); // 다섯 번째 출력
}

실행 결과

 

  Child class 는 Parent class 를 상속 받았으며, Child class 에 Parent class 에 있는 print() 함수가 오버라이딩이 되어있다. main 함수에서 C 객체를 생성한 후 print() 함수를 실행을 한 결과 Child class 의 print() 함수가 실행이 되었다. Parent class 의 print() 함수는 Child class에 의해서 오버라이딩이 되었기 때문이다.

  네 번째를 보면 Parent class의 포인터가 Child 객체를 가리켰지만, Parent class의 print()가 실행이 되었다. Parent class 의 포인터는 해당 class에 종속이 되는 것 이다.

  두 Class 내부의 print2() 함수는 virtual로 선언을 함으로써 Parent class 의 print2() 함수는 그냥 가상 함수가 되었다. 다섯 번째 출력을 보면, Parent class의 포인터가 Child 객체를 가리킨 상황이지만, print2()함수는 virtual로 선언이 된 함수이므로 Parent class의 print2() 함수가 아닌 Child class의 오버라이딩 된 print2()함수가 실행이 되었다.


  정리

  • Overloading : 같은 이름을 가진 함수 및 연산자를 서로 다른 파라미터 리스트를 가진 형태로 정의하는 것
  • Overriding : 상위 클래스에 선언된 멤버와 같은 형태의 멤버를 하위 클래스에 선언하는 것
728x90

'Computer Science > 객체 지향 프로그래밍' 카테고리의 다른 글

Class, Object, Instance 의 차이  (0) 2021.07.27

댓글