12.6 Constructor member initializer lists
https://www.learncpp.com/cpp-tutorial/constructor-member-initializer-lists/
우리는 const variable은 declare와 동시에 initialize가 되어야 한다는 것을 배웠다
그렇다면 일반적으로 constructor를 사용하는 경우에 어떤일이 벌어질까?
class Something
{
private:
const int m_value;
public:
Something()
{
m_value = 1; // error: const vars can not be assigned to
}
};
우리는 앞선 섹션에서 constructor가 member variable을 모두 생성하고
initialzie 한다는 것을 알 수 있었다
그렇다면 위와 같은 경우에는 오류가 발생할 것이다
왜냐하면 const variable을 declare와 동시에 initialize를 하지 않기 때문에
위의 문제는 어떻게 해결해야 할가?
Member initializer lists
c++ 에서 클래스의 member variable을 declare와 동시에 값을 할당하기 위해서 다음과 같은 방법이 있다
class Something
{
private:
const int m_value;
public:
Something(): m_value{ 5 } // directly initialize our const member variable
{
}
};
Something constructor 에 옆에서 initialize를 진행할 수 있다
따라서 위의 const variable은 더 이상 오류가 발생하지 않느다
Initializing array members with member initializer lists
array member도 다음과 같이 initialize할 수 있다
class Something
{
private:
const int m_array[5];
public:
Something(): m_array {} // zero the member array
{
}
};
하지만 c++11이전에는 위와 같이 zero init 밖에 불가능했다
하지만 c++11 부터는 fully initialize할 수 있다
class Something
{
private:
const int m_array[5];
public:
Something(): m_array { 1, 2, 3, 4, 5 } // use uniform initialization to initialize our member array
{
}
};
Initializing member variables that are classes
클래스 member variable도 init 할 수 있다
#include <iostream>
class A
{
public:
A(int x = 0) { std::cout << "A " << x << '\n'; }
};
class B
{
private:
A m_a {};
public:
B(int y)
: m_a{ y - 1 } // call A(int) constructor to initialize member m_a
{
std::cout << "B " << y << '\n';
}
};
int main()
{
B b{ 5 };
return 0;
}
위 코드의 출력은 다음과 같다
A 4
B 5
Formatting your initializer lists
우리는 다양한 방법으로 init list를 작성할 수 있다
class Something
{
private:
int m_value1 {};
double m_value2 {};
char m_value3 {};
public:
Something() : m_value1{ 1 }, m_value2{ 2.2 }, m_value3{ 'c' } // everything on one line
{
}
};
위의 코드에서는 한 라인에 모두 list가 모두 존재한다
class Something
{
private:
int m_value1;
double m_value2;
char m_value3;
public:
Something(int value1, double value2, char value3='c') // this line already has a lot of stuff on it
: m_value1{ value1 }, m_value2{ value2 }, m_value3{ value3 } // so we can put everything indented on next line
{
}
};
위의 코드에서는 다음 라인으로 indentation과 함께 list를 작성하고 있다
class Something
{
private:
int m_value1 {};
double m_value2 {};
char m_value3 {};
float m_value4 {};
public:
Something(int value1, double value2, char value3='c', float value4=34.6f) // this line already has a lot of stuff on it
: m_value1{ value1 } // one per line
, m_value2{ value2 }
, m_value3{ value3 }
, m_value4{ value4 }
{
}
};
위의 코드와 같이 line에 하나의 변수씩 init하는 것도 가능하다
Initializer list order
member variable이 declare된 순서대로 init list를 작성할 필요는 없다
하지만 그렇게 하지 않으면 컴파일러 경고를 줄 수도 있다
그리고 순서를 뒤죽박죽 작성할 이유도 없다
그리고 서로 dependency를 가지도록 init하지 말자
참고로 declare된 순서대로 (initialize list 순서대로가 아닌)
init list의 명령대로 initialize가 진행된다
따라서 dependency를 만들 수가 있다
하지만 그렇게 하지 말라는 소리다
#include <iostream>
class Something
{
private:
int m_value1;
int m_value2;
public:
Something() : m_value1{ 2 }, m_value2{ m_value1 }
{
}
};
위와 같이 코딩하면 m_value2{m_value1}이 올바르게 들어가긴 한다
그런데 만약 반대로 하면 쓰레기 값이 들어간다
#include <iostream>
class Something
{
private:
int m_value1;
int m_value2;
public:
Something() : m_value2{ 2 }, m_value1{ m_value2 }
{
}
};
위와 같이 작성하면 m_value1에 쓰레기 값이 들어간다는 것이다
왜냐하면 list 순서가 아닌 declare 순서대로 init을 하기 때문에...
Summary
Member initializer lists allow us to initialize our members rather than assign values to them.
assign을 통한 초기화가 아닌 initialization을 할수 있게 됐음
member init list 덕분에
이는 constructor를 활용해 initialize하는 유일한 방법이다 (declare 후 assign이 아닌)
Author And Source
이 문제에 관하여(12.6 Constructor member initializer lists), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@ikmy0ung/12.6-Constructor-member-initializer-lists저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)