A. 연산자 오버로딩 (operator overloading)
1. 연산자 오버로딩 기초
a. 연산자 오버로딩이란?
함수 오버로딩 개념을 확대해 연산자에 대해서도 오버로딩을 제공
연산자 오버로딩을 사용자 정의 타입까지 확장할수도 있음
👉 클래스도 하나의 타입임을 확실히 보여줌
b. 연산자 함수(operator function)
연산자를 오버로딩하기 위해서 연산자 함수(operator function)라는 것을 사용
- operator 키워드를 사용하여 연산자를 오버로딩
- 오버로딩할 연산자는 적법한 C++ 연산자여야 하고, operator 키워드와 공백 없이 연결되어 표시해야 함
📘 문법
operator오버로딩할연산자(매개변수목록)
연산자 함수의 장점은 복잡한 함수 이름 대신에 간편하게 연산자를 사용할 수 있다는 점
c. 연산자 함수의 정의 방법
1) 클래스의 멤버 함수로 정의하는 방법
⏳ 예제 : 뺄셈 연산자의 오버로딩, 클래스 내부에 정의
#include <iostream>
using namespace std;
class Position
{
private:
double x_;
double y_;
public:
Position(double x, double y); // 생성자
void Display();
Position operator-(const Position& other); // - 연산자 함수
};
//위 연산자 함수는 아래 함수와 동일, 1)
//Position operator-(const Position& other){
//return Position((x_ + other.x_)/2, (y_ + other.y_)/2);
//};
int main(void)
{
Position pos1 = Position(3.3, 12.5);
Position pos2 = Position(-14.4, 7.8);
Position pos3 = pos1 - pos2;
pos3.Display();
return 0;
}
Position::Position(double x, double y)
{
x_ = x;
y_ = y;
}
//1) 코드를 클래스의 멤버 함수로 정의했다면 여기는 삭제
Position Position::operator-(const Position& other)
{
return Position((x_ + other.x_)/2, (y_ + other.y_)/2);
}
void Position::Display()
{
cout << "두 지점의 중간 지점의 좌표는 x좌표가 " << this->x_ << "이고, y좌표가 " << this->y_ << "입니다." << endl;
}
2) 전역 함수로 정의하는 방법
두 방법의 차이점은 인수의 개수, private 멤버에 대한 접근 여부가 있음
전역 함수로 정의할 경우 private 멤버에 대한 접근을 위해 C++에서 제공하는 프렌드 함수를 사용
⏳ 예제 : 뺄셈 연산자의 오버로딩, 전역 함수로 정의
#include <iostream>
using namespace std;
class Position
{
private:
double x_;
double y_;
public:
Position(double x, double y); // 생성자
void Display();
//전역 함수는 private 멤버인 x_와 y_에 접근하지 못하므로, friend 키워드를 사용하여 프렌드 함수로 선언
friend Position operator-(const Position& pos1, const Position& pos2); // - 연산자 함수
};
int main(void)
{
Position pos1 = Position(3.3, 12.5);
Position pos2 = Position(-14.4, 7.8);
Position pos3 = pos1 - pos2;
pos3.Display();
return 0;
}
Position::Position(double x, double y)
{
x_ = x;
y_ = y;
}
//뺄셈 연산자(-)를 전역 연산자 함수를 사용하여 오버로딩
Position operator-(const Position& pos1, const Position& pos2)
{
return Position((pos1.x_ + pos2.x_)/2, (pos1.y_ + pos2.y_)/2);
}
void Position::Display()
{
cout << "두 지점의 중간 지점의 좌표는 x좌표가 " << this->x_ << "이고, y좌표가 " << this->y_ << "입니다." << endl;
}
✨ 실행결과
두 지점의 중간 지점의 좌표는 x좌표가 -5.55이고, y좌표가 10.15입니다.
2. 오버로딩의 제약 사항
a. 지켜야 하는 사항
1) 전혀 새로운 연산자를 정의 ❌
2) 기본 타입을 다루는 연산자의 의미는 재정의 ❌
따라서 오버로딩 된 연산자의 피 연산자 중 하나는 반드시 사용자 정의 타입이여야 함
ex) 2개의 double 객체를 더하기 위해 사용되는 + 연산자가 - 연산자로 오버로딩이 안됨
3) 오버로딩된 연산자는 기본 타입을 다루는 경우 적용되는 피연산자의 수, 우선순위 및 그룹화를 준수해야 함
ex) 나눗셈 연산자와 같은 이항 연산자는 단항 연산자로 오버로딩이 안됨
4) 오버로딩된 연산자는 디폴트 인수를 사용 ❌
b. 오버로딩할 수 없는 연산자
연산자 | 설명 |
:: | 범위 지정 연산자 |
. | 멤버 연산자 |
.* | 멤버 포인터 연산자 |
? : | 삼항 조건 연산자 |
sizeof | 크기 연산자 |
typeid | 타입 인식 |
const_cast | 상수 타입 변환 |
dynamic_cast | 동적 타입 변환 |
reinterpret_cast | 재해석 타입 변환 |
static_cast | 정적 타입 변환 |
c. 멤버 함수로만 오버로딩 할 수 있는 연산자
전역 함수가 아닌 멤버 함수로만 오버로딩할 수 있음
연산자 | 설명 |
= | 대입 연산자 |
() | 함수 호출 |
[] | 배열 인덱스 |
-> | 멤버 접근 연산자 |
출처 : http://www.tcpschool.com/cpp/cpp_operatorOverloading_intro
'프로그래밍 언어 > C++' 카테고리의 다른 글
C++ OPP 3대요소 : 상속성 (0) | 2023.09.14 |
---|---|
C++ OPP 3대요소 : 캡슐화 (0) | 2023.09.14 |
[자료형(data type)] C++ 파생형 클래스 2 : 생성자와 소멸자 (+39강, 41강) (0) | 2023.09.13 |
[자료형(data type)] C++ 파생형 클래스 1 : 클래스의 기본 (0) | 2023.09.13 |
C++ 범위 : C++ 네임스페이스 (0) | 2023.09.13 |