C++ Chapter 9.13 : initializer_list
카테고리: Cpp
태그: Cpp Programming
인프런에 있는 홍정모 교수님의 홍정모의 따라 하며 배우는 C++ 강의를 듣고 정리한 필기입니다. 😀
🌜 [홍정모의 따라 하며 배우는 C++]강의 들으러 가기!
chapter 9. 연산자 오버로딩 : initializer_list
🔔 소개
- 컨테이너의 초기화를 편리하게 할 수 있도록 도와주는 템플릿이다.
#include <initializer_list>
auto li = { 10, 20, 30 };
li의 타입은 std::initializer_list<int>
이다. 이처럼 {}
중괄호를 사용하여 이니셜라이저 리스트를 생성할때 타입이 auto이면 std::initializer_list
타입의 객체가 된다.
🔔 initializer_list 를 인수로 받는 생성자
std::initializer_list
객체를 인수로 받는 생성자를 구현해 놓으면, 대입 연산자=
와 함께{}
중괄호를 사용해서 생성자를 호출할 수 있다. 이때의 중괄호가 바로std::initializer_list
객체가 되기 때문.
#include <iostream>
#include <cassert>
#include <initializer_list>
using namespace std;
class IntArray
{
private:
unsigned m_length = 0;
int *m_data = nullptr;
public:
IntArray(unsigned length)
: m_length(length)
{
m_data = new int[length];
}
IntArray(const std::initializer_list<int> &list)
:IntArray(list.size()) // 위임 생성자
{
int count = 0;
for (auto & element : list)
{
m_data[count] = element;
++count;
}
}
~IntArray()
{
delete[] this->m_data;
}
friend ostream & operator << (ostream & out, IntArray & arr)
{
for (unsigned i = 0; i < arr.m_length; ++i)
out << arr.m_data[i] >> " ";
out << endl;
return out;
}
};
int main()
{
IntArray int_array = { 1,2,3,4,5 }; // ⭐ 중괄호로 생성자 호출이 가능해짐!
cout << int_array << endl;
return 0;
}
- IntArray(const std::initializer_list<int> &list)
- std::initializer_list 타입의 참조 객체를 인수로 받는 생성자
- ⭐ int 원소들이 들은
{}
중괄호를 인수로 넘기면 그게 바로 std::initializer_list 타입의 객체list
가 된다!
- ⭐ int 원소들이 들은
- 생성자 초기화 리스트에서 위임 생성자로 IntArray(list.size())를 호출한다.
- initializer_list 템플릿은 여러 함수를 지원한다. 그 중 하나인 size()은
{}
, 즉 std::initializer_list 타입의 객체 안에 든 원소의 개수를 리턴한다. {}
크기의 동적 배열을 할당 받아 그 주소를 m_data 에 대입한다.
- initializer_list 템플릿은 여러 함수를 지원한다. 그 중 하나인 size()은
- for문 돌려
{}
, 즉 std::initializer_list 타입의 객체 안에 든 원소들을 m_data 가 가리키는 동적 배열 원소로 복사해준다.- 이때, m_data[count] = list[count] 는 안된다!
- initializer_list 템플릿은 대괄호를 지원하지 않아 list[count]라고 쓸 수 없다.
[]
첨자 연산자 오버로딩이 안되어 있는 것 같다!
- initializer_list 템플릿은 대괄호를 지원하지 않아 list[count]라고 쓸 수 없다.
- 이때, m_data[count] = list[count] 는 안된다!
- std::initializer_list 타입의 참조 객체를 인수로 받는 생성자
- IntArray int_array = { 1,2,3,4,5 };
- std::initializer_list 타입의 참조 객체를 인수로 받는 생성자가 호출된다.
- 문제 없이 IntArray 타입의 객체
int_array
의 멤버 m_data가 가리키는 동적 배열 원소로 1, 2, 3, 4, 5가 초기화 된다. =
대입 연산자는 빼도 상관없다.
🔔 주의 사항
- initializer_list 템플릿은 대괄호를 지원하지 않는다.
- 따라서
std::initializer_list
객체에 첨자[]
를 쓸 수 없다. []
첨자 연산자 오버로딩이 안되어 있는 것 같다!
- 따라서
- initializer_list 템플릿은 얕은 복사를 한다.
- 따라서 동적 메모리를 사용하는 포인터를 사용하는데
{}
즉std::initializer_list
객체끼리 복사해야 하는 경우가 있다면 깊은 복사를 위해 따로 대입 연산자 오버로딩을 구현해주자.
- 따라서 동적 메모리를 사용하는 포인터를 사용하는데
- std::initializer_list 타입의 참조 객체를 인수로 받는 생성자는 생성자 초기화에 사용되는
{}
보다 우선된다.()
말고{}
로 생성자를 호출하는게 자동 형변환을 막아주는 더 엄격한 호출이라고 이 포스트에서 배웠었다.- std::initializer_list 타입의 참조 객체를 인수로 받는 생성자가 구현되어 있다면
{}
로 생성자 호출시 이 생성자가 더 우선한다는 것에 주의하자.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기