들어가면서
기본적으로 연산자는 다음 코드와 같이 기본타입에 대해서는 어떻게 연산할지 규칙이 정해져있다.
int a = 5;
int b = 10;
int result = a + b; //15
하지만, 다음 코드를 보면 사용자 정의의 타입인 Tmp 클래스 타입간의 + 연산은 에러가 발생할 것이다.
Tmp t1{ 5 };
Tmp t2{ 10 };
Tmp result = t1 + t2; //에러!
따라서, 이번 글에서는 사용자 정의의 클래스 타입간의 연산을 오버로딩(재정의) 하는 방법에 대해 알아볼 예정이다.
연산자 오버로딩
연산자 오버로딩은 다음 코드와 같이 클래스 내부에서 멤버함수처럼 정의하면 된다.
다만, 함수명 대신에 operator 키워드와 오버로딩할 연산자를 적어 놓으면 된다.
class ... {
...
public:
리턴타입 operator 오버로딩할연산자(매개변수...){}
}
아래 Tmp클래스의 예제 코드와 함께 살펴보자!
+ 연산자 오버로딩
#include <iostream>
using namespace std;
class Tmp{
private:
int x;
public:
Tmp(int x) : x { x } {}
Tmp operator+(const Tmp& right){ return Tmp{x + right.x}; }
int getX() const { return x; }
};
int main(void){
Tmp t1{ 5 };
Tmp t2{ 10 };
Tmp t3 = t1 + t2;
cout << t3.getX() << endl; //15
return 0;
}
다음과 같이 리턴타입에 'Tmp', 함수명 대신에 'operator 키워드', 오버로딩할 연산자에 '+', 매개변수에는 main함수의 't2' 자리에 위치한 객체를 인자로 받아서, + 연산자에 대한 Tmp 클래스의 연산이 가능해진다.
+= 연산자 오버로딩
#include <iostream>
using namespace std;
class Tmp{
private:
int x;
public:
Tmp(int x) : x { x } {}
Tmp& operator+=(const Tmp& right){
x += right.x;
return *this;
}
int getX() const { return x; }
};
int main(void){
Tmp t1{ 4 };
Tmp t2{ 8 };
(t1 += t2) += 16;
cout << t1.getX() << endl; //28
return 0;
}
다음 코드는 +=operator 수행시 리턴으로 객체 자기 자신을 리턴하게 된다.
(이 문법을 모른다면 아래 글을 보고 오자!
)
C++ : Cascaded Function Calls(멤버함수 체이닝, 연쇄호출)이란?
들어가면서이번 글은 아래 글의 후속편이다. this 포인터에 대해 잘 모르겠으면 아래 글을 보고 다시 오자! https://logicallaw.tistory.com/entry/C-클래스-내부의-this-포인터의-역할 C++ : 클래스 내부의 this
logicallaw.tistory.com
== 연산자 오버로딩
#include <iostream>
using namespace std;
class Tmp{
private:
int x;
public:
Tmp(int x) : x { x } {}
bool operator==(const Tmp& right){
return (x == right.x);
}
int getX() const { return x; }
};
int main(void){
Tmp t1{ 4 };
Tmp t2{ 8 };
if (t1 == t2){
cout << "true" << endl;
}
else {
cout << "false" << endl;
}
return 0;
}
++ 연산자 오버로딩(전위)
#include <iostream>
using namespace std;
class Tmp{
private:
int x;
public:
Tmp(int x) : x { x } {}
Tmp& operator++(){ //전위증가
++x;
return *this;
}
int getX() const { return x; }
};
int main(void){
Tmp t1{ 4 };
++t1;
//t1++;은 에러가 난다.
cout << t1.getX() << endl; //5
return 0;
}
전위 증가는 Rvalue가 아닌 Lvalue를 리턴하며 값을 먼저 증가시키고 객체 자기 자신을 리턴한다.
따라서, 객체 자기 자신을 역참조 포인터를 사용하여 리턴해야한다.
++ 연산자 오버로딩(후의)
#include <iostream>
using namespace std;
class Tmp{
private:
int x;
public:
Tmp(int x) : x { x } {}
Tmp& operator++(){ //전위증가
++x;
return *this;
}
Tmp operator++(int){ //후위증가
Tmp temp{*this};
x++;
return temp;
}
int getX() const { return x; }
};
int main(void){
Tmp t1{ 4 };
t1++;
cout << t1.getX() << endl; //5
return 0;
}
반면, 후의 증가는 Lvalue가 아닌 Rvalue를 리턴하며 객체 자기 자신을 먼저 리턴하고 값을 증가시킨다.
따라서, 먼저 증가하기 전의 모습을 담기 위한 temp 변수에 저장하고 값을 증가시키고 리턴값으로 temp를 리턴한다.
추가로, 클래스 내 operator++의 모습이 비슷해보이는데 매개변수 목록이 달라서 서로 다른 함수(오버로딩)로 인식되는 것도 알고 넘어가자!
'C++' 카테고리의 다른 글
C++ : Cascaded Function Calls(멤버함수 체이닝, 연쇄호출)이란? (0) | 2024.03.20 |
---|---|
C++ : 클래스 내부의 this 포인터의 역할(this->멤버/(*this).멤버) (0) | 2024.03.20 |
C++ : 변환생성자(conversion constructor)란? (매개변수 생성자와의 차이점은?) (0) | 2024.03.20 |
C++ : friend 키워드란? (0) | 2024.03.18 |
C++ : cin >> int배열;은 왜 불가능 할까? (0) | 2024.03.15 |
들어가면서
기본적으로 연산자는 다음 코드와 같이 기본타입에 대해서는 어떻게 연산할지 규칙이 정해져있다.
int a = 5; int b = 10; int result = a + b; //15
하지만, 다음 코드를 보면 사용자 정의의 타입인 Tmp 클래스 타입간의 + 연산은 에러가 발생할 것이다.
Tmp t1{ 5 }; Tmp t2{ 10 }; Tmp result = t1 + t2; //에러!
따라서, 이번 글에서는 사용자 정의의 클래스 타입간의 연산을 오버로딩(재정의) 하는 방법에 대해 알아볼 예정이다.
연산자 오버로딩
연산자 오버로딩은 다음 코드와 같이 클래스 내부에서 멤버함수처럼 정의하면 된다.
다만, 함수명 대신에 operator 키워드와 오버로딩할 연산자를 적어 놓으면 된다.
class ... { ... public: 리턴타입 operator 오버로딩할연산자(매개변수...){} }
아래 Tmp클래스의 예제 코드와 함께 살펴보자!
+ 연산자 오버로딩
#include <iostream> using namespace std; class Tmp{ private: int x; public: Tmp(int x) : x { x } {} Tmp operator+(const Tmp& right){ return Tmp{x + right.x}; } int getX() const { return x; } }; int main(void){ Tmp t1{ 5 }; Tmp t2{ 10 }; Tmp t3 = t1 + t2; cout << t3.getX() << endl; //15 return 0; }
다음과 같이 리턴타입에 'Tmp', 함수명 대신에 'operator 키워드', 오버로딩할 연산자에 '+', 매개변수에는 main함수의 't2' 자리에 위치한 객체를 인자로 받아서, + 연산자에 대한 Tmp 클래스의 연산이 가능해진다.
+= 연산자 오버로딩
#include <iostream> using namespace std; class Tmp{ private: int x; public: Tmp(int x) : x { x } {} Tmp& operator+=(const Tmp& right){ x += right.x; return *this; } int getX() const { return x; } }; int main(void){ Tmp t1{ 4 }; Tmp t2{ 8 }; (t1 += t2) += 16; cout << t1.getX() << endl; //28 return 0; }
다음 코드는 +=operator 수행시 리턴으로 객체 자기 자신을 리턴하게 된다.
(이 문법을 모른다면 아래 글을 보고 오자!
)
C++ : Cascaded Function Calls(멤버함수 체이닝, 연쇄호출)이란?
들어가면서이번 글은 아래 글의 후속편이다. this 포인터에 대해 잘 모르겠으면 아래 글을 보고 다시 오자! https://logicallaw.tistory.com/entry/C-클래스-내부의-this-포인터의-역할 C++ : 클래스 내부의 this
logicallaw.tistory.com
== 연산자 오버로딩
#include <iostream> using namespace std; class Tmp{ private: int x; public: Tmp(int x) : x { x } {} bool operator==(const Tmp& right){ return (x == right.x); } int getX() const { return x; } }; int main(void){ Tmp t1{ 4 }; Tmp t2{ 8 }; if (t1 == t2){ cout << "true" << endl; } else { cout << "false" << endl; } return 0; }
++ 연산자 오버로딩(전위)
#include <iostream> using namespace std; class Tmp{ private: int x; public: Tmp(int x) : x { x } {} Tmp& operator++(){ //전위증가 ++x; return *this; } int getX() const { return x; } }; int main(void){ Tmp t1{ 4 }; ++t1; //t1++;은 에러가 난다. cout << t1.getX() << endl; //5 return 0; }
전위 증가는 Rvalue가 아닌 Lvalue를 리턴하며 값을 먼저 증가시키고 객체 자기 자신을 리턴한다.
따라서, 객체 자기 자신을 역참조 포인터를 사용하여 리턴해야한다.
++ 연산자 오버로딩(후의)
#include <iostream> using namespace std; class Tmp{ private: int x; public: Tmp(int x) : x { x } {} Tmp& operator++(){ //전위증가 ++x; return *this; } Tmp operator++(int){ //후위증가 Tmp temp{*this}; x++; return temp; } int getX() const { return x; } }; int main(void){ Tmp t1{ 4 }; t1++; cout << t1.getX() << endl; //5 return 0; }
반면, 후의 증가는 Lvalue가 아닌 Rvalue를 리턴하며 객체 자기 자신을 먼저 리턴하고 값을 증가시킨다.
따라서, 먼저 증가하기 전의 모습을 담기 위한 temp 변수에 저장하고 값을 증가시키고 리턴값으로 temp를 리턴한다.
추가로, 클래스 내 operator++의 모습이 비슷해보이는데 매개변수 목록이 달라서 서로 다른 함수(오버로딩)로 인식되는 것도 알고 넘어가자!
'C++' 카테고리의 다른 글
C++ : Cascaded Function Calls(멤버함수 체이닝, 연쇄호출)이란? (0) | 2024.03.20 |
---|---|
C++ : 클래스 내부의 this 포인터의 역할(this->멤버/(*this).멤버) (0) | 2024.03.20 |
C++ : 변환생성자(conversion constructor)란? (매개변수 생성자와의 차이점은?) (0) | 2024.03.20 |
C++ : friend 키워드란? (0) | 2024.03.18 |
C++ : cin >> int배열;은 왜 불가능 할까? (0) | 2024.03.15 |