연산자 다중정의란 C++에 정의된 연산자가 사용자가 선언한 클래스의 객체에 대하여 사용할수있도록 정의하는것
⚠️연산자 다중정의주의사항
연산자의 의미를 바꾸지않는다
연산자의 고유한특성이 유지되도록한다.
- 우선순위,피연산자의수는 불변 해야 한다
- 전위표기와 후위표기 연산자의 의미는 유지 해야 한다.
연산자 다중정의 대상
클래스의 객체 간 대입 및 이동 대입 연산자
*특히 동적할당을 받는 포인터를 포함하는경우 고려해야함
수치형 객체의 산술 연산자 다중정의
*교환법칙도 함께 고려함
두 객체를 비교하기 위한 관계 연산자의 다중정의
스트림 입력을 및 출력을 위한 <<,>>연산자
⚠️다중정의를 할수없는 연산자
멤버 선택 연산자 ( . )
맴버 포인터 연산자 ( .* )
유효범위 연산자 ( :: )
조건 연산자 ( ? : )
연산자 다중정의위치
- 클래스의 멤버로 정의하는방법
- 연산자의 구현 과정에서 객체의멤버를 액세스 할수있음
- 클래스외부에서 정의하는방법
- 클래스의 멤버가 아니므로, 객체의 private맴버는 직접 사용할수없음
단항 연산자의 다중정의
피연산자가 1개인 연산자
전위표기 다중정의 형식
//전위 표기 다중정의형식
Returntype ClassName::opertor opSymbol()
{
.....
}
예:전위표기 ++ 연산자의 다중정의
class IntClass1{
int a;
public:
IntClass1(int n=0;):a(n) {};
IntClass & operator ++ (){
++a;
return *this;
}
int getValue () const {
return a;
}
}
전위 표기 연산자는 반환값이 “참조형 자신” 이다
매개변수는 없다.
후위표기 다중정의 형식
//후위 표기 다중정의형식
Returntype ClassName::opertor opSymbol(int)
{
.....
}
❗후위표기는 파라미터로 ‘int’를 받는다 인수전달의 의미가 아니라 후위표기법을 사용하는 단항 연산자이다
예:후위표기 ++ 연산자의 다중정의
class IntClass2{
int a;
public:
IntClass2(int n=0;) : a(0){};
IntClass2 operator ++(int){
Intclass2 tmp(*this);
++a;
return tmp
};
};
후위표기법에서는 객체를 반환하며
매개변수는 “int” 이다
이항 연산자의 다중정의
이항 연산자 다중정의 형식
ReturnClasss ClassName::operator opSymbol(ArgClass arg)
{
....
}
- opSymbol : + - * / && || 등의 이항 연산자 기호
- 객체 자신이 좌측 피연산자, arg가 우측 피연산자에 해당됨
→ a + b 라면 a가 객체자신 arg가 b임
예: 복소수객체 complex20bj 로 풀이
복소수 객체 + 복소수 객체
수식: complex20bj1 + complex20bj2
Complex2 Complex2::operator + (const Complex2 &c)const {
Complex2 tmp(*this);
tmp.rPart += c.rPart;
tmp.iPart += c.iPart;
return tmp;
};
자신(*this) 객체를 복사한 tmp에 더할 c 객체에 r.Part , i.Part 를 더한 tmp를 반환해준다.
복소수 객체+ 실수
수식 : complex20bj + 10.0
Complex2 Complex2::operator + (double r)const {
return Complex2(rPart + r, iPart);
};
double값이 묵시적형변환으로 복소수 + 복소수 로 처리됨
실수+ 복소수 객체
좌측피연산자가 실수이므로 C++에서 미리 정해둔 데이터이기에 연산자를 다중정의할수없음
→클래스에 속하지 않는 외부의 별도 연산자로 정의함
수식 : 10.0 + conplex20bj
Complex2 operator + (double r, const Complex2 &c){
retrun Complex2(r + c.rPart,c.iPart);
};
매개변수를 두개를 받음 좌측(첫번쨰)매개변수는 실수 , 우측 매개변수는 복소수 객체이다
⚠️하지만 위의 방식은 c.rPrat , c.iPrat 는 private멤버를 사용했기떄문에 오류가 발생한다 !!!
첫번째 해결책 접근가능 메소드만들기
Complex2에 preivate 멤버를 액세스할수있는 맴버할수를 만든다
// 클래스를 정의할때 private 멤버를 접근할수있는 메소드를 만든다
class Complex2{
double rPart,iPart;
public:
double real() const {return rPart;}
double imag() const {return iPart;}
};
// 사용시에는 메소드를 불러사용할수 있다.
Complex2 operator + (double r, const Complex2 &c){
retrun Complex2(r + c.real(),c.imag() );
}
하지만 이렇게 사용하게되면 메소드를 일일이 설저해주어야 하고
클래스의 캡슐화즉 정보은닉의 의미가 조금 사라지게된다
두번째 해결책 friend
// 연산자 다중정의시 friend를 선언해준다
class Complex2{
double rPart,iPart;
public:
.....
friend Comp lex2 operator + (double r, Complex2 &c);
// friend로 선언된 다중정의 연산자는 private멤버에 접근할수있다.
Complex2 operator + (double r, const Complex2 &c){
retrun Complex2(r + c.rPart(),c.iPart() );
}
friend로 선언된 다중정의 연산자는 private멤버에 접근할수 있다
'컴퓨터 과학 > C++' 카테고리의 다른 글
lvalue , rvalue 차이점 정확하게 이해하자 (0) | 2023.12.04 |
---|---|
C++ 포인터, 동적 메모리할당 new와 delete 정리 (2) | 2023.12.03 |
C++ const 한정어란? 위치에따른 다른결과값정리 요약 (2) | 2023.12.03 |
3.4 inline 함수 (0) | 2023.12.01 |
C++ 객체지향 언어 추상화와 캡슐화의 정리 (0) | 2023.08.20 |