연산자 다중정의란 C++에 정의된 연산자가 사용자가 선언한 클래스의 객체에 대하여 사용할수있도록 정의하는것

⚠️연산자 다중정의주의사항

연산자의 의미를 바꾸지않는다

연산자의 고유한특성이 유지되도록한다.

  • 우선순위,피연산자의수는 불변 해야 한다
  • 전위표기와 후위표기 연산자의 의미는 유지 해야 한다.

연산자 다중정의 대상

클래스의 객체 간 대입 및 이동 대입 연산자

*특히 동적할당을 받는 포인터를 포함하는경우 고려해야함

수치형 객체의 산술 연산자 다중정의

*교환법칙도 함께 고려함

두 객체를 비교하기 위한 관계 연산자의 다중정의

스트림 입력을 및 출력을 위한 <<,>>연산자

⚠️다중정의를 할수없는 연산자

멤버 선택 연산자 ( . )

맴버 포인터 연산자 ( .* )

유효범위 연산자 ( :: )

조건 연산자 ( ? : )

연산자 다중정의위치

  • 클래스의 멤버로 정의하는방법
    • 연산자의 구현 과정에서 객체의멤버를 액세스 할수있음
  • 클래스외부에서 정의하는방법
    • 클래스의 멤버가 아니므로, 객체의 private맴버는 직접 사용할수없음
    →필요하다면 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멤버에 접근할수 있다

+ Recent posts