프로그래밍 언어/C++

C++ 연산자 오버로딩

순정법사 2023.09.13

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

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com