▣ 생성자 처리 위임
● 위임 생성자(delegating constructor) 선언
▷ C++11 이후에 생긴 생성자
▷ 생성자 작성 코드의 중복을 줄이는 효과가 있다.
▷ 초기화 리스트에 앞에서 선언됐던 생성자를 사용해서 새로운 생성자를 선언하게 한다.
- 위임 생성자: 앞에서 선언된 생성자를 이용하여 선언되는 생성자
- 타겟 생성자: 위임의 대상이 되는 생성자
● 예시 - VecF 클래스
....
class VecF {
int n;
float *arr;
public:
VecF(int d, float* a=nullptr) : n{ d } {
arr = new float[d];
if (a) memcpy(arr, a, sizeof(float) *n);
}
/*복사 생성자*/
VecF(const VecF& fv) : n{ fv.n } {
arr = new float[n];
memcpy(arr, fv.arr, sizeof(float) *n);
}
.....
};
▼
C++11 이전에는 생성자를 선언할 때 다른 생성자를 선언할 수 없었지만, C++11 이후부터는 앞서 정의된 생성자를 이용해서 새로이 생성자를 만들 수 있게 바꼈다.
....
class VecF {
int n;
float *arr;
public:
VecF(int d, float* a=nullptr) : n{ d } {
arr = new float[d];
if (a) memcpy(arr, a, sizeof(float) *n);
}
/*복사 생성자*/
VecF(const VecF& fv) : VecF(fv.n, fv.arr) {}
.....
};
▷ VecF(const VecF& fv) : VecF(fv.n, fv.arr)에서 fv.ndl int고, fv.arr이 float*이므로 바로 위에 정의된 생성자가 호출된다. d에는 fv.n이, float* 매개변수에는 fv.arr이 들어가거 원래 정의됐던 생성자가 동작하게 한다.
▷ 불필요한 코드 중복을 줄였다.
▣ 초기화 리스트 생성자
● 초기화 리스트 생성자(initializer-list constructor)
▷ 첫 번째 매개변수가 std::initializer_list<Type>인 생성자다.
▷ 초기화 리스트를 매개변수로 받을 수 있도록 만든 생성자다.
▷ std::initializer_list<Type> 클래스란?
- 지정된 자료형의 값들을 { } 안에 나열한 리스트
- 헤더 파일은 #include <initializer_list> 로 설정한다.
멤버함수 | 용도 |
begin( ) | 첫 번째 요소에 대한 포인터를 반환한다. |
end( ) | 마지막 요소의 다음 위치에 대한 포인터를 반환한다. |
size( ) | initialize_list의 원소 수를 반환한다. |
- {1, 2, 3}에서 begin은 '1', end는 '3' 이 아닌 '3' 다음 위치를 가리킨다.
- 예시 - initializer__list <int> list{1, 2, 3}; 일 때, list.begin( ) = 1이 된다.
● 초기화 리스트 생성자 예시
class VecF {
int n;
float *arr;
public:
VecF(int d, const float* a = nullptr) : n{ d } {
arr = new float[d];
if (a) memcpy(arr, a, sizeof(float) * n);
}
VecF(initializer_list<float> lst)
: n{static_cast<int>(lst.size()) } {
arr = new float[n];
copy(lst.begin(), lst.end(), arr);
}
};
int main()
{
float a[4] = {1.0f, 2.0f, 3.0f, 4.0f};
VecF v1(4,a); // 배열의 개수도 매개변수로 받아야 했다.
VecF v2(2.0f, 4.0f, 6.0f, 8.0f); //초기화 리스트 생성자
}
▷ n에 lst.size( )를 저장한다. 하지만 이 객체는 정수값이 아니기 때문에 에러가 나올 수 있다. 그래서 정수형으로 형변환하기 위해 static_cast<int>를 해준다.
▷ n이 초기화 리스트로 초기화 된다.
▷ arr에 float값을 저장하기 위해 포인터에 new float[n]을 통해 n개의 데이터를 저장할 수 있는 float형 배열을 할당해준다.
▷ arr에 이 초기화 리스트에 들어 있는 값을 복사한다. 복사는 memcpy로 해도 되지만 copy()라는 함수를 써본다.
▷ copy()에서 매개변수로 (1)맨 앞의 원소에 대한 포인터, (2)다음에 맨 뒤 원소 그 다음을 가리키는 포인터를 제시해주고 (3)그 다음에 복사 받을 배열/포인터를 지정해준다. --> initializer_list 데이터의 처음부터 끝까지 그대로 arr에 복사하게 된다.
▷ 객체를 만들 때 배열을 만들고 그것을 가지고 초기화해주는 생성자를 이용하지 않고, 초기화 리스트를 이용해서 직접 객체를 만드는 것이 가능해지므로 더 편리할 수 있다.
'Programming > C++' 카테고리의 다른 글
C++ 언어 기초 (10) - 연산자 다중정의 II (0) | 2020.09.03 |
---|---|
C++ 언어 기초 (9) - 연산자 다중정의 (0) | 2020.08.31 |
[C++] 복소수 Complex 연산 클래스 만드는 방법 (0) | 2020.08.28 |
[C++] 자료구조 스택 Stack 구현하기 (0) | 2020.08.28 |
C++ 언어 기초 (8) - static 데이터 멤버와 static 멤버함수 (0) | 2020.08.28 |