[C++ 문법] '변환 생성자'
간단하게 매개변수가 한 개인 생성자를 '변환 생성자'라고 합니다. 이러한 '변환 생성자'는 '사용자 코드'에서의 편의를 위해 묵시적으로 호출될 수 있습니다. 예제를 살펴보겠습니다.
class MyData {
private:
int m_nData = 0;
public:
MyData(int nParam) : m_nData{ nParam } { cout << "MyData(int)" << endl; }
MyData(const MyData& rhs) : m_nData{ rhs.m_nData } {
cout << "MyData(const MyData&)" << endl;
}
int GetData() const { return m_nData; }
void SetData(int nParam) { m_nData = nParam; }
}
void Func(MyData param) {
cout << "Func(): " << param.GetData() << endl;
}
void main() {
Func(10); // Func() 함수의 매개변수는 'MyData' 타입이지만, int 값을 넘겨줍니다.
// 그럼 Func() 함수는 int 매개변수 하나를 가지는 '생성자'를 찾아 호출합니다.
}
위의 예제는 컴파일 에러가 나지않고 잘 실행됩니다. Func() 함수는 int형 매개변수가 아니라, MyData 사용자 정의 타입인데 왜 잘 실행되는걸까요? 그 이유가 바로 위에서 설명했듯이 '사용자 코드'에서의 편의를 위해 묵시적으로 '변환 생성자'를 호출했기 때문입니다. 위의 코드에서 Func(10);은 사실상 아래 코드와 같습니다.
Func(MyData{ 10 });
Func() 함수의 매개변수를 '&'로 받으면 이 이름없는 '임시 객체'를 '참조'할 수 있게 됩니다. 위와 똑같은 코드에서 Func() 함수의 매개변수만 '&'로 수정해보겠습니다.
void Func(const MyData& param) {
cout << "Func(): " << param.GetData() << endl;
}
void main() {
Func(10); // Func(MyData{ 10 });
}
'변환 생성자'는 '사용자 코드'에서의 편의를 위해 제공되지만, 제공받는 편의에 비해 치뤄야할 비용이 더 큰 생성자입니다. '사용자'가 의도하지 않았음에도 불구하고 묵시적으로 호출되어 '임시 객체'가 생성되는 문제가 발생할 수 있습니다. 묵시적으로 '변환 생성자'가 호출되지 않도록 막기 위해선 'explicit' 키워드를 사용합니다.
class MyData {
private:
int m_nData = 0;
public:
explicit MyData(int nParam) : m_nData{ nParam } { cout << "MyData(int)" << endl; }
/* 아래 코드는 위와 동일합니다. */
}
자, 여기서 추가로 생각해봐야할 문제가 있습니다. 우리가 지금껏 살펴봤던 변환은 'int -> MyData' 타입으로의 변환이었습니다. 그러면 반대로 'MyData -> int' 타입으로의 변환도 가능할까요? 물론 가능합니다. MyData 클래스에 '형변환 연산자'를 추가해보겠습니다.
class MyData {
private:
int m_nData = 0;
public:
explicit MyData(int nParam) : m_nData{ nParam } { cout << "MyData(int)" << endl; }
operator int(void) { return m_nData; } // 해당 클래스는 'int'형으로 형변환이 가능해집니다.
/* 아래 코드는 위와 동일합니다. */
}
마지막으로, 'MyData -> int'형으로 형변환을 할 때는 C++ 스타일의 'static_cast<int>(형변환 연산자)'를 사용합니다.
cout << static_cast<int>(a) << endl; // '(int)a'는 지양합니다.
'Programming > C C++' 카테고리의 다른 글
[C++ 문법] '연산자 함수(연산자 오버로딩)' (0) | 2019.05.23 |
---|---|
[C++ 문법] '이동 생성자' (0) | 2019.05.22 |
[C++ 문법] '복사 생성자' (0) | 2019.05.20 |
[C++ 문법] '정적(static) 멤버' (0) | 2019.05.20 |
[C++ 문법] 'mutable' 예약어와 'const_cast<>' 형변환 연산자 (0) | 2019.05.20 |
댓글
이 글 공유하기
다른 글
-
[C++ 문법] '연산자 함수(연산자 오버로딩)'
[C++ 문법] '연산자 함수(연산자 오버로딩)'
2019.05.23 -
[C++ 문법] '이동 생성자'
[C++ 문법] '이동 생성자'
2019.05.22 -
[C++ 문법] '복사 생성자'
[C++ 문법] '복사 생성자'
2019.05.20 -
[C++ 문법] '정적(static) 멤버'
[C++ 문법] '정적(static) 멤버'
2019.05.20