연산자 중첩(operator overloading)
<연산자 중첩(operator overloading)>
- 연산자 오버로딩
- 다형성을 구현하는 방법 중 하나
- 기존에 사용하고 있는 연산자(+, -, *, /, =, %, ++, <, !, +=, <<, ==, &&, &, [ ], ( ), "," , -> 등)의 기능을 클래스에서 새롭게 정의하여 사용하는 것
- 주로 숫자나 문자를 대상으로 하는 연산자들을 해당 클래스에서는 재정의하여 사용자들에게 편리한 프로그래밍을 제공
<연산자의 개념과 종류>
<C언어 연산자의 우선순위와 결합성>
<연산자 중첩의 필요성>
- i+j라는 식은 두 자료 i와 j를 더하라는 의미
- 일반적으로 i와 j는 같은 형으로 int형, float형, double형 수이다.
- 10+20, 12.5+3.7 등
- i와 j가 문자열(i="I Love", j="You!" )이라면 i+j는 C에서는 불가능
- C 에서는 strcat함수로 다음과 같이 구현한다.
#include <stdio.h> #include <string.h> int main() { char i[]="I Love "; char j[]="You!"; printf("%s",strcat(i,j)); return 0; }
- 문자열의 경우에도 k=i+j="I Love You!"가 되면 얼마나 좋을까!
- 2차원 좌표계의 한 점을 표현하는 경우 (2, 3), (3, 4) 등으로 x좌표값과 y좌표값으로 표현한다.
- 수학에서는 (2, 3)+(3, 4) 하면 각 성분끼리 더해져서 (5, 7)이된 된다.
- 프로그래밍에서 사용하는 "+"연산자에 이러한 기능은 없다.
- +연산자가 다양한 덧셈에 사용 가능하도록 연산자의 의미를 확대 재정의하는 방법이 연산자 중첩
- 더한다는 의미의 연산은 모두 “+”연산자 하나로 구현
<* : 선언문(구두점) vs. 실행문(연산자)>
- 선언문: 포인터를 선언(구두점)할 때
- 실행문: 주소로 가서 값을 가져올 때(연산자)
- *이 선언문에서 사용되는지 실행문에서 사용되는지에 따라서 다르다
- int x=10,y;// 정수형 변수 x,y선언 - int *px; // 포인터 px선언, 선언문에서 *****는 포인터를 선언하는 구두점 - px=&x; // 정수형 변수 x의 주소를 포인터 px에 대입 - y=*px; // px가 저장하고 있는 주소로 가서 값을 가져옴 - 실행문에서 *****는 참조 연산자
- 실행문에서 *는 포인터 변수에 저장된 주소로 가서 실제 데이터 값을 가져오는데 사용하는 참조 연산자로 간접 값(indirect value) 연산자, dereferencing 연산자라고도 함
- px에 저장된 주소(&x)로 가서 값(x의 내용)을 가져오므로 y에는 10이 대입됨
- *px=20; //x=20;
- 포인터 px가 가리키는 주소에 20을 대입 - px가 x의 주소를 가지고 있으므로 변수 x의 값도 바뀜 - 주소로 가서 값을 바꾸는 간접적인 방법으로 변경
<this 포인터>
- this 포인터는 자동적으로 시스템이 만들어 주는 포인터
- 멤버가 호출될 때 그 멤버가 속한 객체를 가르킨다.
- 객체를 통하여 멤버를 호출할 때 컴파일러는 객체의 포인터 즉 주소를 this포인터에 넣은 다음 멤버를 호출한다.
- this 포인터는 멤버를 호출한 객체의 const 포인터이다.
- 멤버함수를 수행하고 나서 그 결과로 객체 자신을 되돌릴 경우 return *this라고 하면 된다.
- 멤버함수에서 볼 때 this 포인터는 어떤 객체가 자신을 호출했는지 알고자 하는 경우
사용한다.- 연산자 중첩에서 사용
- 클래스의 멤버함수 내에서 다른 클래스에 자기 자신을 매개변수로 넘길 때 사용
<연산자 중첩 형식>
- 단항연산자 중첩
리턴형 operator 연산자명(); //전치, ++x 리턴형 operator 연산자명(int); //후치, x++
- 이항연산자 중첩
리턴형 operator 연산자명(매개변수);
<단항 연산자 중첩>
- 단항 연산자에는 ++, --, -(부호)가 있다.
- 피연산자가 하나이다
x++ //x를 1증가 --y //y를 1감소 -5 //5를 마이너스
- 단항연산자를 중첩할 때는 매개변수가 필요 없다.
<전치 단항 연산자 중첩>
- 전치 연산자(prefix operator)란 변수명 앞에 연산자가 오는 것을 말한다(++x, --i 등).
- 전치 연산자는 연산이 먼저 일어나고 대입이 된다.
int x=10; std::cout<<++x; //11
- 전치 단항 연산자 중첩의 형식
리턴형 operator 연산자명(); void operator ++() { ++i; }
<x, y의 값을 하나 증가시키는 함수 만들기>
#include <iostream> using namespace std; class Point { int x; int y; public: Point(int i, int j) { x = i; y = j; } int getX() { return x; } int getY() { return y; } void upPrint() { ++x; ++y; cout << x << " " << y << endl; } Point up() { ++x; ++y; return *this; } }; int main() { Point p1(3, 4); p1.upPrint(); p1.up(); cout << p1.getX() << ","; cout << p1.getY(); return 0; }
<전치 단항 연산자 중첩>
#include <iostream> using std::cout; class Point { int x; int y; public: Point(int i, int j) { x = i; y = j; } int getX() { return x; } int getY() { return y; } Point operator ++() { ++x; ++y; return *this; //객체를 반환한다. //즉, x,y모두 리턴 } }; int main() { Point p1(2, 3); ++p1; cout << p1.getX() << ","; cout << p1.getY(); return 0; }
<전치 단항 연산자 중첩(정의를 클래스 밖으로)>
#include <iostream> using std::cout; class Point { int x; int y; public: Point(int i, int j) { x = i; y = j; } int getX() { return x; } int getY() { return y; } Point operator ++(); //선언 }; Point Point::operator ++() //정의 { ++x; ++y; return *this; //객체를 반환한다. x,y모두 리턴 } int main() { Point p1(3, 4); ++p1; cout << p1.getX() << ","; cout << p1.getY(); return 0; }
<후치 단항 연산자 중첩>
- 후치 연산자(postfix operator)란 변수명 뒤에 연산자가 오는 것을 말한다.
x++, i-- 등
- 후치 연산자는 대입이 먼저 일어나고 연산이 된다.
int x=10; std::cout<<x++; //10
- 후치 단항 연산자 중첩의 형식
리턴형 operator 연산자명(int); void operator ++(int) { i++; }
<후치 단항 연산자 중첩>
#include <iostream> using std::cout; class Point { int x; int y; public: Point(int i, int j) { x = i; y = j; } int GetX() { return x; } int GetY() { return y; } Point operator --(int); }; Point Point::operator--(int) { x--; y--; return *this; //객체를 반환한다. } int main() { Point p1(3, 4); p1--; cout << p1.GetX() << ","; cout << p1.GetY(); return 0; }
<이항 연산자 중첩>
- 이항 연산자란 +, -, ×, ÷, % 등 연산자 양쪽에 피연산자가 필요한 연산자이다.
- 이항 연산자 중첩에서는 한 개의 매개변수가 필요하다.
- 연산자의 왼쪽 피연산자가 연산자 함수의 주체가 되고, 오른쪽 피연산자만 있으면 되기 때문이다.
- 즉 "1+2" 라는 연산에서 왼쪽 피연산자 1이 "+"연산자의 주체이다.
<이항 연산자 중첩 : +연산자>
#include <iostream> using std::cout; class Point { int x, y; // private변수 public: Point() { x = 0; y = 0; } Point(int xx, int yy) { x = xx; y = yy; } Point operator +(Point ob); int getX() { return x; } int getY() { return y; } }; Point Point::operator +(Point ob) { Point temp; temp.x = x + ob.x; temp.y = y + ob.y; return temp; } int main() { Point ob1(3, 5), ob2(4, 6), ob3; cout << ob3.getX() << "," << ob3.getY() << " "; ob3 = ob1 + ob2; //이항연산자 + 호출 cout << ob3.getX() << "," << ob3.getY(); return 0; }
<Point클래스의 "*"연산자 중첩>
#include <iostream> using std::cout; class Point { int x, y; // private변수 public: Point() { x = 0; y = 0; } Point(int xx, int yy) { x = xx; y = yy; } Point operator +(Point ob); int getX() { return x; } int getY() { return y; } }; Point Point::operator +(Point ob) { Point temp; temp.x = x + ob.x; temp.y = y + ob.y; return temp; } int main() { Point ob1(3, 5), ob2(4, 6), ob3; cout << ob3.getX() << "," << ob3.getY() << " "; ob3 = ob1 + ob2; //이항연산자 + 호출 cout << ob3.getX() << "," << ob3.getY(); return 0; }
<Point클래스의 "=="연산자 중첩>
#include <iostream> using std::cout; using std::endl; class Point { int x, y; //private변수 public: Point() { x = 0; y = 0; } Point(int xx, int yy) { x = xx; y = yy; } char operator ==(Point ob); int getX() { return x; } int getY() { return y; } }; char Point::operator ==(Point ob) { return (x == ob.x && y == ob.y) ? 'T' : 'F'; // 같으면 T, 다르면 F } int main() { Point ob1(3, 5), ob2(4, 6), ob3(3, 5); cout << (ob1 == ob2) << endl; //괄호 조심 cout << (ob1 == ob3) << endl; return 0; }
<형변환 함수(type conversion function)>
- 한 객체의 자료형을 다른 객체의 자료형으로 변환시키고자 할 때 형변환 함수(type conversion function)를 이용한다.
operator 리턴형() {return 변환값;}
- 리턴형은 변환하고자 하는 자료형이고 변환값은 변환을 수행할 값이다.
- 형변환 함수는 매개변수를 갖지 않으며 형변환을 수행하는 클래스의 멤버함수이어야 한다.
<연산자 중첩의 제약>
- 모든 연산자가 중첩될 수 있는 것은 아니다.
- 다음 연산자들은 중첩이 불가능하다.
. .* ::
- 이 연산자들은 첫 번째 피연산자로 그 객체를 갖는다는 미리 정의된 의미를
가지므로(.*는 멤버 포인터 연산자)?: sizeof
<연산자 중첩시 주의 사항>
- 우선 순위를 변경할 수 없다.
- 단항 연산자를 다항 연산자로 변경할 수 없다.
- 임의의 새로운 연산자(**, <>)를 정의할 수 없다.
- operator+()와 operator=()를 정의했다고 해서 operator+=()이 정의되지는 않는다.
- 기본 자료형(int, char, float 등)에 대해서는 중첩을 허용하지 않는다.
- "=" 연산자를 제외하고, 연산자는 파생(자식) 클래스에 상속된다.
<연산자 중첩이 부적절한 이유는?>
- %연산자의 연산이 그 고유의 사용과 관련되어 있지 않기 때문이다
Point Point::operator %(Point ob) { x=x+ob.x; y=y+ob.y; return *this; }
<Point클래스에 대해서 이항 - 연산자를 중첩하시오.>
#include <iostream> using std::cout; class Point { int x, y; // private변수 public: Point() { x = 0; y = 0; } Point(int xx, int yy) { x = xx; y = yy; } Point operator -(Point ob); int getX() { return x; } int getY() { return y; } }; Point Point::operator -(Point ob) { Point temp; temp.x = x - ob.x; temp.y = y - ob.y; return temp; } int main() { Point ob1(3, 5), ob2(4, 6), ob3; cout << ob3.getX() << "," << ob3.getY() << " "; ob3 = ob1 - ob2; //이항연산자 + 호출 cout << ob3.getX() << "," << ob3.getY(); return 0; }
Author And Source
이 문제에 관하여(연산자 중첩(operator overloading)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@totoromin0308/연산자-중첩operator-overloading저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)