일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- docker
- github
- Unity
- C언어 포인터
- gitlab
- Algorithm
- HTML
- c언어
- c# winform
- Data Structure
- c#
- Flutter
- 구조체
- c# 추상 클래스
- Houdini
- 유니티
- git
- dart 언어
- jupyter lab
- 깃
- c# 윈폼
- vim
- 도커
- jupyter
- C++
- 다트 언어
- C# delegate
- Python
- 플러터
- 포인터
- Today
- Total
nomad-programmer
[Programming/C++] 임시객체로의 자동 형 변환과 형 변환 연산자(Conversion Operator) 본문
[Programming/C++] 임시객체로의 자동 형 변환과 형 변환 연산자(Conversion Operator)
scii 2021. 2. 5. 22:57C++에서는 객체간의 대입연산을 허용한다. 당연하게도 두 객체의 자료형이 일치할 때에만 대입연산이 가능하다.
#include <iostream>
#pragma warning(disable: 4996)
using std::cout;
using std::cin;
using std::endl;
class Number {
private:
int num;
public:
Number(int n = 0) : num(n) {
cout << "Number(int n=0)" << endl;
}
Number& operator=(const Number& ref) {
cout << "operator=()" << endl;
num = ref.num;
return *this;
}
void ShowNumber() const {
cout << num << endl;
}
};
int main(const int argc, const char* const argv[]) {
Number num;
num = 30;
num.ShowNumber();
return 0;
}
/* 결과
Number(int n=0)
Number(int n=0)
operator=()
30
*/
출력 결과를 통해 알 수 있는 것은 다음과 같다.
// 1단계. 임시객체의 생성
num = Number(30);
// 2단계. 임시객체를 대상으로 하는 대입 연산자의 호출
num.operator=(Number(30));
여기서의 핵심은 임시객체의 생성이다. 그리고 이러한 임시객체의 생성을 통해 대입연산이 진행되는데에는 다음과 같은 문법적 기준이 존재한다.
A형 객체가 와야 할 위치에 B형 데이터(또는 객체)가 왔을 경우, B형 데이터를 인자로 전달받는 A형 클래스의 생성자 호출을 통해서 A형 임시객체를 생성한다.
따라서 위의 예제에서는 'Number형 객체가 와야 할 위치에 int형 데이터가 와서, int형 데이터를 인자로 전달받는 Number 클래스의 생성자 호출을 통해 Number형 임시객체를 생성한 것' 이다. 그리고나서 두 Number객체를 대상으로 대입연산을 진행한다.
이렇듯, 기본자료형 데이터를 객체로 형 변환하는 것은 적절한 생성자의 정의를 통해 얼마든지 가능하다. 그렇다면 반대로 객체를 기본 자료형 데이터로 형 변환하는 것도 가능할까?
가능하다. 예를 들어 앞서 정의한 Number 클래스를 대상으로 다음과 같은 덧셈연신이 가능 하려면,
int main(void) {
Number num1;
num1 = 30;
Number num2 = num1 + 20;
num2.ShowNumber();
return 0;
}
Number 클래스가 + 연산자를 오버로딩하고 있거나, num1이 int형 데이터로 변환이 되어야 한다.
#include <iostream>
#pragma warning(disable: 4996)
using std::cout;
using std::cin;
using std::endl;
class Number {
private:
int num;
public:
Number(int n = 0) : num(n) {
cout << "Number(int n=0)" << endl;
}
Number& operator=(const Number& ref) {
cout << "operator=()" << endl;
num = ref.num;
return *this;
}
// 형 변환 연산자의 오버로딩
operator int() {
return num;
}
void ShowNumber() const {
cout << num << endl;
}
};
int main(const int argc, const char* const argv[]) {
Number num1;
num1 = 30;
Number num2 = num1 + 20;
num2.ShowNumber();
return 0;
}
/* 결과
Number(int n=0)
Number(int n=0)
operator=()
Number(int n=0)
50
*/
위의 예제에서 정의한 형 변환 연산자는 다음과 같다.
operator int() {
return num;
}
이렇듯 형 변환 연산자는 반환형을 명시하지 않는다. 하지만 return문에 의한 값의 반환은 얼마든지 가능하다. 그리고 오버로딩 된 연산자의 이름이 operator+ 이면, + 연산자가 등장했을 때 호출되는 것과 유사하게 operator int는 다음의 의미로 이해하면 된다.
int형으로 형 변환해야 하는 상황에서 호출되는 함수이다.
즉, int형으로 형 변환되어야 하는 상황에서 호출이 되며, 이 때 return문에 의해 반환되는 값이 int형으로의 형 변환 결과가 되는 것이다. 그래서 다음 문장의 실행과정에서
Number num2 = num1 + 20;
num1 객체의 operator int 함수가 호출되어, 이 때 반환되는 값 30과 20의 덧셈연산이 진행되며, 이 연산의 결과로 num2 객체가 생성된 것이다.
'Programming > C++' 카테고리의 다른 글
[Programming/C++] 함수 템플릿과 특수화(Specialization) (0) | 2021.02.06 |
---|---|
[Programming/C++] 표준 string 클래스의 분석 (0) | 2021.02.06 |
[Programming/C++] ( )연산자의 오버로딩과 펑터(Functor) (0) | 2021.02.05 |
[Programming/C++] 스마트 포인터(Smart Pointer) (0) | 2021.02.05 |
[Programming/C++] new/delete 연산자 오버로딩 (0) | 2021.02.05 |