티스토리 뷰
10-1 연산자 오버로딩의 이해와 유형
operator+라는 이름의 함수
#include <iostream>
#include <cstring>
using namespace std;
class Point
{
private:
int xpos, ypos;
public:
Point(int x = 0, int y = 0) :xpos(x), ypos(y)
{}
void ShowPosition() const
{
cout << '[' << xpos << ", " << ypos << ']' << endl;
}
Point operator+(const Point& ref)
{
Point pos(xpos + ref.xpos, ypos + ref.ypos);
return pos;
}
};
int main(void)
{
Point pos1(3, 4);
Point pos2(10, 20);
Point pos3 = pos1.operator+(pos2);
pos1.ShowPosition();
pos2.ShowPosition();
pos3.ShowPosition();
return 0;
}
[3, 4]
[10, 20]
[13, 24]
Point pos3=pos1+pos2;
이 문장은 컴파일이 되며, 덧셈 저장결과가 리턴된다.
pos1+pos2가 pos1.operator+(pos2)의 다른 표현일거다.
->무언가 변환의 규칙이 있을 것이다.
대화로 풀어보는 연산자 오버로딩
-객체도 기본 자료형 변수처럼 덧셈, 뺄샘, 곱셈 등을 하려고 한다.
-'operator' 키워드와 '연산자'의 이름을 묶어 함수를 호출한다.
-Point pos3=pos1+pos2를 pos1.operator+(pos2)로 바꿔서 해석
연산자를 오버로딩 하는 두 가지 방법
-멤버함수에 의한 연산자 오버로딩
-전역함수에 의한 연산자 오버로딩
pos1+pos2 ->pos1.operator+(pos2)
->operator+(pos1, pos2) 전역변수로 선언된 경우
오버로딩이 불가능한 연산자의 종류
. 멤버 접근 연산자
.* 멤버 포인터 연산자
:: 범위 지정 연산자
?: 조건 연산자(3항 연산자)
sizeof (바이트 단위 크기 계산)
typeid RTTI 관련 연산자
static_cast 형변환 연산자
dynamic_cast 형변환 연산자
const_cast 형변환 연산자
reinterpret_cast 형변환 연산자
C++의 문법규칙을 보존하기 위해 오버로딩을 제한한다.
오버로딩이 가능한 연산자
=
()
[]
->
이들은 객체를 대상으로만 쓰이기 때문에, 멤버 기반으로만 오버로딩을 허용한다.
연산자 오버로딩 하는데 있어서의 주의사항
1) 본래의 의도를 벗어난 오버로딩은 좋지않다.
pos1+pos2을 덧셈 외에 다른 결과가 나오는 건 좋지 않다.
2) 연산자의 우선순위와 결합성은 바뀌지 않는다.
3) 매개변수의 디폴트 값 설정이 불가능하다.
피연산자의 자료형에 따라 오버로딩 한 함수의 호출이 결정되는데, 매개 변수를 디폴트로 줄 수 없다.
4) 연산자의 순수 기능까지 뺏을 수는 없다.
int oprator+라 쓰고 *연산을 정의할 수 없다.
연산자 오버로딩이라 이름을 붙은 이유를 이해하셨나요?
int num=3+4;
Point pos3= pos1+pos2;
함수가 오버로딩 되면 전달되는 인자에 따라서 호출되는 함수가 달라진다.
연산자가 오버로딩 되면, 피연산자의 종류에 따라서 연산의 방식이 달라진다.
10-2 단항 연산자의 오버로딩
증가, 감소 연산자의 오버로딩
1증가 연산자 ++
2감소 연산자 --
++pos;//pos는 Point 객체
++pos -> pos.operator++(); 멤버함수
-> operator++(pos); 전역함수
로 변환된다.
전위증가와 후위증가의 구분
++pos -> pos.operator++();
pos++ -> pos.operator++(int);
--pos -> pos.operator++();
pos-- -> pos.operator--();
int를 전달하면 후위증가가 가능하다.
여기서의 int는 일반적인 자료형이 아니라 전위증가와 후위증가를 구분하느 역할을 한다.
const Point operator--(Point& ref, int)
{
const Point retobj(ref);
ref.xpos -= 1;
ref.ypos -= 1;
return retobj;
}
반환형에서의 const 선언과 const 객체
const 함수 내에서는 const 함수의 호출만 허용하도록 한다.
int main(void)
{
const Point pos(3,4);
const Point &ref=pos;
}
연산을 이용한 값이 새로 pos에 덧붙여지는 것이 아니다.
다시 본론으로 돌아와서
const Point operator--(Point& ref, int)
{
const Point retobj(ref);
ref.xpos -= 1;
ref.ypos -= 1;
return retobj;
}
int main(void)
{
Point pos(3, 5);
(pos++)++;
(pos--)--;
}
위의 두 문장은 const로 선언되어 있지 않기 때문에 에러를 발생시킨다.
10-3 교환법칙 문제의 해결
#include <iostream>
#include <cstring>
using namespace std;
class Point
{
private:
int xpos, ypos;
public:
Point(int x=0, int y=0):xpos(x),ypos(y)
{}
void ShowPosition() const
{
cout << '[' << xpos << ", " << ypos << ']' << endl;
}
Point operator*(int times)
{
Point pos(xpos * times, ypos * times);
return pos;
}
};
int main(void)
{
Point pos(1, 2);
Point cpy;
cpy = pos * 3;
cpy.ShowPosition();
cpy = pos * 3 * 2;
cpy.ShowPosition();
return 0;
}
[3, 6]
[6, 12]
cpy = pos*3;
cpy= 3*pos; // 3.operator*(pos)로는 해석 불가능!
교환법칙의 성립을 위한 구현
Point operator*(int times, Point&ref)
{
Point pos(ref.xpos*times, ref.ypos*times);
return pos;
}
Point operator*(int times,Point&ref)
{
return ref×
}
로 오버로딩을 하면 해결된다.
10-4 cout, cin 그리고 endl의 정체
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
namespace mystd
{
using namespace std;
class ostream
{
public:
void operator<<(char* str)
{
printf("%s", str);
}
void operator<<(char str)
{
printf("%c", str);
}
void operator<<(int num)
{
printf("%d", num);
}
void operator<<(double e)
{
printf("%g", e);
}
void operator<<(ostream& (*fp)(ostream& ostm))
{
fp(*this);
}
};
ostream& endl(ostream& ostm)
{
ostm << '\n';
fflush(stdout);
return ostm;
}
ostream cout;
}
int main(void)
{
using std::cout;
using mystd::endl;
cout << "Simple String";
cout << endl;
cout << 3.14;
cout << endl;
cout << 123;
endl(cout);
return 0;
}
함수가 오버로딩되어서 어떤 것을 넣어도 출력이 그대로 된다.
#include <iostream>
namespace mystd
{
using namespace std;
class ostream
{
public:
ostream& operator<<(char* str)
{
printf("%s", str);
return *this;
}
ostream& operator<<(char str)
{
printf("%c", str);
return* this;
}
ostream& operator<<(int num)
{
printf("%d", num);
return*this;
}
ostream& operator<<(double e)
{
printf("%g", e);
return*this;
}
ostream& operator<<(ostream& (*fp)(ostream& ostm))
{
return fp(*this);
}
};
ostream& endl(ostream& ostm)
{
ostm << '\n';
fflush(stdout);
return ostm;
}
ostream cout;
}
int main(void)
{
using std::cout;
using mystd::endl;
cout << 3.14 << endl << 123 << endl;
}
<<, >> 연산자의 오버로딩
int main(void)
{
Point pos(3, 4);
cout<<pos<<endl; //[3, 4] 출력
}
cout<<pos가 되려면 pos도 오버로딩이 되어 있어야한다.
- Total
- Today
- Yesterday
- 강화학습
- 티스토리챌린지
- 여인권
- Python
- 파이썬
- 류근관
- 심리학
- 보세사
- 사회심리학
- 일본어
- c++
- 정보처리기사
- C
- 열혈프로그래밍
- 통계
- 인지부조화
- 뇌와행동의기초
- stl
- 데이터분석
- 일본어문법무작정따라하기
- C/C++
- 통계학
- 코딩테스트
- K-MOOC
- 오블완
- 인프런
- 백준
- 일문따
- 회계
- 윤성우
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |