C++문법 공부

생성자 맴버 초기화 리스트를 사용한 객체 맴버의 초기화

막뇌 2023. 6. 11. 21:42

객체 맴버중에 const 속성을 가진 맴버 변수나

래퍼런스(참조) 타입의 맴버변수를 가진 경우가 있을 수 있습니다.

레퍼런스 타입이나 읽기전용 타입이 없을 경우 정상적으로 빌드 되는 모습입니다.


사례1.

읽기전용 타입 const 맴버변수를 선언 하고 객체를 선언 했는데 에러가 발생합니다.


 

사례2.

레퍼런스(참조) 타입 맴버변수를 선언 했을 때에도 에러가 발생합니다.

두가지 사례에서 객체를 선언 한 후에 초기화를 하려 했더니 컴파일러가 에러를 알리고 있습니다.

레퍼런스 타입이나 const  속성을 가진 맴버 변수에 값을 할당하지 않고 객체를 선언 할 경우 무조건 생성자를 참조해야만 한다는 (지금 생성자가 없다는)에러를 보게 됩니다.

두가지 타입은 반드시 값을 가진 상태로 초기화를 해줘야 하기 때문입니다.

 

에러메시지가 보여주는 대로 디폴트 생성자를 추가해 보았습니다.


<사례1-디폴트 생성자 사용의 경우 에러 발생>

 

<사례2-디폴트 생성자 사용의 경우 에러 발생>


생성자조차도 이 문제를 완벽히 해결할 수가 없습니다.

생성자보다 더 강력한, 더 이전에 초기화를 할 수 있는 곳이 필요합니다.

이것이 바로 생성자의 초기화 리스트 입니다.

#include <iostream>
using namespace std;

class ExampleConstructor
{
public:
	const int X;	//const 타입 맴버 변수 X 선언
	int& ref;	//레퍼런스 타입 맴버 변수 ref 선언
	int baby;

	ExampleConstructor();	//디폴트 생성자 선언
};

//디폴트 생성자 정의를 통해 값을 초기화
ExampleConstructor::ExampleConstructor()
	: X(23), ref(baby)					//생성자의 맴버 초기화리스트 사용 맴버이름(값), 맴버이름(값)
{
	baby = 46;
}



int main()
{
	ExampleConstructor ec;

	cout << "ec.X : " << ec.X << endl;
	cout << "ec.ref: " << ec.ref << endl;
	
	return 0;
}

초기화리스트의 모양을 살펴 보겠습니다.

 

ExampleConstructor::ExampleConstructor()
: X(23), ref(baby)
{ baby = 46; }

중괄호와 생성자 원형 사이에 위치하여 콜론(:)으로 시작하는 형태를 보여주고 있습니다.

중괄호안에 있는 소스코드 보다 먼저 실행한다는 느낌을 주죠?

이렇게 반드시 초기화 해야만 하는 맴버변수들은 생성자의 초기화 리스트를 사용해서 초기화 해야만 합니다.

이러한 초기화리스트의 사용은 디폴트 생성자 사용에만 국한된 것이 아닙니다.

#include <iostream>
using namespace std;

class ExampleConstructor
{
public:
	const int X;	//const 타입 맴버 변수 X 선언
	const int Y;	//const 타입 맴버 변수 Y 선언
	int& ref;	//레퍼런스 타입 맴버 변수 ref 선언
	int baby;

	ExampleConstructor();	//디폴트 생성자 선언
	ExampleConstructor(int coordinateX, int coordinateY, int& humanJr);	//3개의 인자가 있는 생성자를 추가
};

//디폴트 생성자 정의를 통해 값을 초기화
ExampleConstructor::ExampleConstructor()
	:X(3), Y(15), ref(baby)
{
	baby = 46;
}

//인자를 받는 형태의 생성자를 추가 하면서 초기화 리스트를 사용
ExampleConstructor::ExampleConstructor(int coordinateX, int coordinateY, int& humanJr)
	:X(coordinateX), Y(coordinateY), ref(humanJr)
{
	baby = 46;
}



int main()
{
	int a = 12;	
	
	//인자를 받는 형태로 객체를 생성	
	ExampleConstructor ec(5, 25, a);
	
	cout << "ec.X : " << ec.X << endl;
	cout << "ec.Y : " << ec.Y << endl;
	cout << "ec.ref: " << ec.ref << endl;
	
	return 0;
}

인자를 3개 받는 형태로 객체를 생성하면서 생성자를 호출하는 예제 코드입니다.

인자를 받는 형태의 생성자가 호출되면서, 초기화 리스트를 실행할 때 받은 인자를 활용해서 맴버 구성원들을 초기화 하는 모습을 볼 수 있습니다.

ExampleConstructor::ExampleConstructor(int coordinateX, int coordinateY, int& humanJr)
	:X(coordinateX), Y(coordinateY), ref(humanJr)
{
	baby = 46;
}

 

 

선언

ExampleConstructor ec(5, 25, a);

실행

 

핵심 : 초기화 리스트를 활용하면 생성자 내부 소스코드보다 먼저 초기화 하는것이 가능하다.
반드시 값이 할당된 상태로 초기화 해야하는 const 타입, ref 타입들을 다룰 때에는 반드시 필요하다.