[C++] 연산자 중복 (feat. 프랜드 함수)

2020. 6. 19. 02:37·🖥️ 컴퓨터공학 🖥️/C | C++
반응형

 

출처 => C++ How to Program (Detitel / Prenticehall) / 현재 그리고 미래지향적인 C++ 프로그래밍(장석우, 임정목 / 비앤씨에듀케이션)

https://beomnaegol.tistory.com/entry/C-%EC%97%B0%EC%82%B0%EC%9E%90-%EC%98%A4%EB%B2%84%EB%A1%9C%EB%94%A9-3-%EC%A0%84%EC%9C%84%EC%A6%9D%EA%B0%90%EA%B3%BC-%ED%9B%84%EC%9C%84%EC%A6%9D%EA%B0%90
http://blog.daum.net/coolprogramming/73

 

연산자 중복의 정의

▶ 연산자 중복이랑 C++에서 제공하는 기본 타입이 아닌 클래스 타입(사용자가 정의하는 타입)에도 연산자를 사용할 수 있도록 하는 문법이다. 

▶ 예를 들어, 

cout<<2+3<<endl;
// 5

위의 소스코드는 컴파일이 가능하지만,

cout<<빨간색+노란색<<endl;
// 컴파일 오류!

이는 당연히 오류가 생긴다.

우리는 직관적으로 빨간색과 노란색을 섞으면 주황색이 나온다는 것을 알지만 컴파일러는 이런 사실을 알고 있지 않기 때문이다. 

▶ 따라서 컴파일러 내부에 정의되어 있지 않은 자료형의 연산도 제공할 수 있도록 하여 코드의 직관성, 가독성, 그리고 편의성을 제공하고자 만든 문법이 연산자 중복이다. 

 

연산자 중복의 특징은 다음과 같다.

▶ C++에 본래 있는 연산자만 가능하다. **나 %%와 같은 기괴한 형태의 연산자는 불가능!

▶ 연산자는 함수 형태로 구현이 된다.

▶ 반드시 클래스와 관계를 가져야 한다.

▶ 모든 연산자가 중복 가능하지 않는다. 가령, ::는 범위를 지정해주는 연산자이기 때문에 연산자 중복으로서 기능을 담당할 수가 없다.

 

▶ 연산자는 크게 2가지의 방법으로 구현이 가능하다. 

1. 외부 함수로 구현하고 클래스에 프랜드 함수로 선언

2. 클래스의 멤버함수로 구현

 

1. 외부 함수로 구현하고 클래스에 프랜드 함수로 선언하는 예제

#include<iostream>
using namespace std;

class Rect {
private:
	int width, height;
public:
	Rect(int width=0, int height=0) {
		this->width = width;
		this->height = height;
	}
	void show();
	friend Rect operator -(Rect a, Rect b);
};

Rect operator-(Rect a, Rect b) {
	Rect c;
	c.width = a.width - b.width;
	c.height = a.height - b.height;
	return c;
}

void Rect:: show() {
	cout << "width :" << width 
    << "," << "height" << height<<endl;
}
void main() {
	Rect a(5, 8), b(1, 3), c;
	c = a - b;
	c.show();
}

 

 

2. 클래스의 멤버함수로 연산자를 구현하는 예제

#include<iostream>
using namespace std;


class Rect {
private:
	int width, height;
public:
	Rect(int width = 0, int height = 0) {
		this->width = width;
		this->height = height;
	}
	Rect operator +(Rect r);
	void show();
};

Rect Rect::operator +(Rect r) {
	Rect c;
	c.width = this->width + r.width;
	c.height = this->height + r.height;
	return c;
}

void Rect::show() {
	cout << "width:" << width 
    << "," << "height:" << height << endl;
}

void main() {
	Rect a(5, 8);
	Rect b(1, 5);
	Rect c;

	c = a + b;
	c.show();
}

 

 

 

 

외부함수로 구현한 연산자와 클래스의 멤버함수로 구현한 연산자의 차이점

▶ 두 가지의 방법이 약간 다르다. 이를 설명하자면 다음과 같다.

 

▶ 위의 예시와 비교를 해보기에 앞서 1번 예시는 외부 함수로 구현하고 클래스에 프랜드 함수로 선언하는 방법이고, 2 번 예시는 클래스의 멤버함수로 연산자를 구현하는 예제임을 다시 한 번 강조한다.

▶ 먼저 위의 예시이다.

Rect operator-(Rect a, Rect b) {
	Rect c;
	c.width = a.width - b.width;
	c.height = a.height - b.height;
	return c;
}

▶ Rect클래스의 연산자인 -, 그리고 그 연산자의 사용되는 객체 a와 b. Rect 클래스의 또 다른 예시인 c는 a의 가로 세로를 b의 가로 세로와 합한 값이다. 

▶ 위의 코드는 직관적이다. a의 가로 세로, b의 가로 세로를 합하고 그 합한 결과인 c라는 객체를 return 한다. operator 연산자가 Rect형이니 c로 return을 할 수 있다.

 

▶ 그 다음은 2번 예제의 소스코드이다. 

Rect Rect::operator +(Rect r) {
	Rect c;
	c.width = this->width + r.width;
	c.height = this->height + r.height;
	return c;
}

▶ 1번 예시는 Rect 클래스의 객체 a ,b가 다 있었던 반면에 이 소스코드는 r이라는 객체밖에 없다. 왜 그럴까?

 

 

▶ 위의 그림이 답해주고 있다. 클래스의 멤버함수로 구현하는 경우(2번 예시), 클래스 자신이 이미 1개의 인자 역할을 하기 때문에 1번처럼 2개로 객체를 지정하면 이 연산자 함수에 매개변수가 너무 많습니다는 오류 메시지가 발생하게 된다. 따라서 클래스의 멤버함수로 선언할 때는 위와 같이 해줘야 한다.

 

전위 연산자와 후위 연산자

▶ 조건문을 쓸 때 흔히 ++나 --를 사용한다. 이를 증감연산자라고 부르는데, 변수의 앞에 붙으면 전위증감, 뒤에 붙으면 후위증감이라고 부른다. 이는 연산자 오버로딩에서도 똑같이 적용되지만 구현을 하기 위해서는 특별한 법칙을 알아야 한다.

 

▶ 먼저 전위 연산자이다. 

#include<iostream>
using namespace std;

class Power {
	int kick;
	int punch;
public:
	Power(int kick = 0, int punch = 0) {
		this->kick = kick;
		this->punch = punch;
	}
	void show();
	Power operator++();
};
void Power::show() {
	cout << "kick=" << kick 
    << "," << "punch=" << punch << endl;
}
Power Power::operator++() {
	kick++;
	punch++;
	return *this;
}

void main() {
	Power a(3, 5), b;
	a.show();
	b.show();
	b = ++a;
	a.show();
	b.show();
}

 

 

 

▶ 다음은 후위 연산자이다. 

#include<iostream>
using namespace std;

class Power {
	int kick;
	int punch;
public:
	Power(int kick = 0, int punch = 0) {
		this->kick = kick;
		this->punch = punch;
	}
	void show();
	Power operator++(int x); //후위 ++연산자 함수 선언 
};
void Power::show() {
	cout << "kick=" << kick 
		<< "," << "punch=" << punch << endl;
}
Power Power::operator++(int x) {
	Power tmp = *this;
	//증가 이전 객체 상태를 저장
	kick++;
	punch++;
	return tmp;//증가 이전의 객체 return 
}

void main() {
	Power a(3, 5), b;
	a.show();
	b.show();
	b =a++;//후위 연산자 사용
	a.show();//a의 파워 1증가
	b.show();//b는 a가 증가되기 이전의 상태를 가짐
}

 

 

▶ 이 두 연산자 역시 차이점이 존재한다. 전위 연산자 함수와 후위 연산자 함수를 비교해보자.

//전위 연산자
Power Power::operator++() {
	kick++;
	punch++;
	return *this;
}

▶ kick과 punch를 각각 1만큼 증가시킨 뒤에, 그 증가가 된 객체를 return하는 것을 볼 수 있다. 

 

//후위 연산자
Power Power::operator++(int x) {
	Power tmp = *this;
	//증가 이전 객체 상태를 저장
	kick++;
	punch++;
	return tmp;//증가 이전의 객체 return 
}

▶ 그와 달리, 후위 연산자는 증가 이전의 객체를 tmp라는 Power 클래스의 또다른 객체에 저장하고, 증가를 시킨 뒤에 tmp를 return함을 알 수 있다.

728x90
반응형

'🖥️ 컴퓨터공학 🖥️ > C | C++' 카테고리의 다른 글

[C++] 상속(Inheritance) - 2 (feat. 가상 함수와 추상클래스)  (0) 2020.06.20
[C++] 상속(Inheritance) - 1 (feat. 개념, 상속 접근 지정자)  (0) 2020.06.19
[C++] 프랜드 함수  (0) 2020.06.19
[C++] 생성자와 소멸자  (0) 2020.06.18
[C++] 포인터 변수 (feat. * / & / **)  (0) 2020.06.17
'🖥️ 컴퓨터공학 🖥️/C | C++' 카테고리의 다른 글
  • [C++] 상속(Inheritance) - 2 (feat. 가상 함수와 추상클래스)
  • [C++] 상속(Inheritance) - 1 (feat. 개념, 상속 접근 지정자)
  • [C++] 프랜드 함수
  • [C++] 생성자와 소멸자
공대생 배기웅
공대생 배기웅
군노답 미필 공대생 배기웅의 대학생활을 갈아 넣은 블로그
    반응형
  • 공대생 배기웅
    글쓰는공대생의 IT블로그
    공대생 배기웅
  • 전체
    오늘
    어제
    • 분류 전체보기 (166)
      • 🖊️ 공대생 글쓰기 🖊️ (17)
        • 공대생 회고록 (4)
        • 공대생의 끄적끄적 (4)
        • 슬기로운 공대생활 (9)
        • 무한도전 대학원생 (0)
      • 📈 산업공학 📈 (14)
        • 금융, 파생상품 (13)
        • 통계 (0)
        • 선형대수 (0)
        • 보험, 리스크관리 (0)
        • 재무회계 (1)
      • 🖥️ 컴퓨터공학 🖥️ (92)
        • 머신러닝, 딥러닝 (12)
        • 텐서플로우, 케라스 (1)
        • 알고리즘 (24)
        • 웹 (5)
        • Python (3)
        • C | C++ (23)
        • Java (15)
        • 코드 에러 모음집 (9)
      • 😙 취미, 교양 😙 (2)
        • 영어공부 (1)
        • 일본어회화 공부 (1)
      • 🔍 정보 공유 🔍 (38)
        • 대학생 외부활동 정보 (2)
        • 개발자관련 정보 (3)
        • 대입 논술 입시자료 정보 (22)
        • 프로그램 세팅 (11)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 링크

  • 공지사항

    • [공지] 글쓰는 공대생입니다 😃
  • 인기 글

  • 태그

    백준
    equals프레임워크
    자바
    조작자
    프로그래머스
    이클립스
    경제성공학
    예외
    재귀함수
    C++
    OOP
    알고리즘
    프랜드함수
    무작위 변수
    acmicpc
    Operator
    데이터베이스
    Java
    객체지향
    스캐너
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
공대생 배기웅
[C++] 연산자 중복 (feat. 프랜드 함수)
상단으로

티스토리툴바