4장 연산자 다중 정의 _c++

hans·2023년 7월 31일
0

c++ 먹어보자

목록 보기
4/6
post-thumbnail

목차

  • 1.연산자 다중 정의를 하는 목적
  • 2.연산자 함수의 활용

1.연산자 다중 정의

c++ 개발자는 기본적으로 사용자에 입장에서 코드를 작성해야 한다.
사용자가 사용하기 쉬운 코드는 추상성,직관성,편리성이 높은 코드를 의미한다
다음 코드를 보자

    MyClass a;
	a.Append(3, int);

	MyClass a;
	a += 3; 

둘다 기존 a에 3을 추가하는 내용이지만 사용자 입장에서는 두 코드의 난이도는 다르다.
그렇기에 우리는 사용자가 더욱 소프트웨어를 사용할수 있게 클래스의 연산자 다중 정의를 통해
여러 기능을 제공해야 한다

2.연산자 함수 활용

연산자 함수는 연산자를 호출할 수 있는 메서드 이다
기본적인 예시 코드를 살펴보자

class CMyData
{
public:
	CMyData()
	{

	}

	CMyData(int number)
		:m_nData(number)
	{

	}
	~CMyData()
	{

	}

	operator int()
	{
		return m_nData;
	}

	int operator+(CMyData rhs)
	{
		this->m_nData = this->m_nData + rhs.m_nData;
		return m_nData;
	}

	void operator=(int nParam)
	{
		m_nData = nParam;
	}

private:
	int m_nData = 0;
};


//사용자 코드
int main(void)
{
	CMyData a(3);
	CMyData b(4);

	CMyData c;
	c = a + b;

	cout << c << endl;

	c = 4 ;

	cout << c << endl;
}

출력결과
7
4

앞서 코드에서 중요하게 봐야할 부분은 c = a+b , c=4 부분이다
두 코드는 사용자 입장에서 연산자 처럼 보이지만 정확히 함수 이다.
그렇기에 기본 연산으로 만든 함수는 절대로 실패 해서는 안된다.
그렇기에 사용자에 맞춰 예외처리 등이 필요하다.

여기서 생각을 조금 더 확장해 보자

만약 다음처럼 코드 작성되면 어떻게 될까?

a = b = 5;

당연히 오류가 발생한다
b = 5는 우리가 int 값을 매계변수 로 받는 연산자를 정의했지만 a = b 는 클래스를 매계변수로 하는 연산자를 정의하지 않았다.
그러면 위에 문제를 해결하는 방법에 대해 알아보자

첫번쨰로 int 값을 반환하도록 연산자를 정의하는것이다

void operator=(int nParam)
	{
		m_nData = nParam;
	}

기존코드

int operator=(int nParam)
	{
		m_nData = nParam;
		return m_nData;
	}

바뀐 코드

이렇게 바꾸면 정상적으로 출력이 되는것을 확인할수 있다.
하지만 이러한 방식에도 문제점이 존재한다
b=5까지는 정상적으로 연산자를 진행하면 된다 하지만 b=5가 반환하는 값은 int
그렇다면 a=b는 엄연히 클래스대 클래스 연산인데 int반환 연산자로 호출이 된다.

그렇기에 연산자를 하나더 정의 하자

CMyData operator=(CMyData rhs)
	{
		m_nData = rhs.m_nData;
		return m_nData;

	}

클래스 반환 연산자

이렇게 바꾸면 b=5는 int형 연산자로 a=b는 클래스형 연산자로 제대로 작동한다
하지만 여기서 임시객체 문제를 마주하게 된다
클래스 반환 연산자를 살펴 보면 기본적으로 클래스 인스턴스를 2개를 임시객체로 만든다
(매개변수로 받은 rhs 1개 , return 으로 만드는 클래스 1개)
임시객체는 성능저하에 원인으로 지금부터 임시객체 문제 해결을 위해 2가지를 바꿔보자

- 1.함수의 매개변수가 클래스인 경우 무조건 참조로 받는 것이 좋다

CMyData operator=(const CMyData& rhs)
	{
		m_nData = rhs.m_nData;
		return m_nData;

	}

함수의 매개변수 클래스를 참조형으로 받으면 불필요한 임시객체를 만들지 않아도 된다.
참고로 참조형으로 받을떄 const도 세트로 붙여주자 !!

  • 2.참조 반환을 이용하자
CMyData& operator=(const CMyData& rhs)
	{
		m_nData = rhs.m_nData;
		return *this;

	}

우리가 대입을 하기위해서 operatro=에 복사본을 만든 다음에 대입을 할필요가 없다.
기본적으로 operator= 자체를 참조 반환을 통해 인스턴스를 줄일 수 있다

profile
방구석여포

0개의 댓글

관련 채용 정보