본문 바로가기
개발/C, C++

C++ - 생성자 초기화 리스트 (Constructor Member Initializer List)

by 피로물든딸기 2021. 7. 26.
반응형

C, C++ 전체 링크

 

class의 생성자에서 아래와 같이 변수를 초기화 할 수 있다.

#include <stdio.h>
#include <iostream>

using namespace std;

class TEST
{
public:
	int value1;
	int value2;

	TEST()
	{
		cout << "생성자 호출" << endl;
		value1 = 1;
		value2 = 2;
	}

	void printValue()
	{
		cout << value1 << ", " << value2 << endl;
	}
};


int main(void)
{
	TEST test;

	test.printValue();

	return 0;
}

 

c++ 11부터는 선언과 동시에 초기화도 가능하다.

public:
	int value1 = 1;
	int value2 = 2;

	TEST()
	{
		cout << "생성자 호출" << endl;
	}

 

생성자 초기화 리스트를 이용하면 아래와 같이 바꿀 수 있다.

public:
	int value1;
	int value2;

	TEST() 
		: value1(1), value2(2)
	{
		cout << "생성자 호출" << endl;
	}

 

생성과 동시에 원하는 값으로 초기화하는 경우는 아래와 같다.

#include <stdio.h>
#include <iostream>

using namespace std;

class TEST
{
public:
	int value1;
	int value2;

	TEST() 
		: value1(1), value2(2)
	{
		cout << "생성자 호출" << endl;
	}

	TEST(int val1, int val2)
	{
		value1 = val1;
		value2 = val2;
		cout << "생성자 호출 2" << endl;
	}

	void printValue()
	{
		cout << value1 << ", " << value2 << endl;
	}
};

int main(void)
{
	TEST test = TEST(3, 4);
	
	test.printValue();

	return 0;
}

 

생성자 초기화 리스트를 이용하면 아래처럼 수정할 수 있다.

	TEST(int val1, int val2) 
		: value1(val1), value2(val2)
	{
		cout << "생성자 호출 2" << endl;
	}

멤버 변수가 참조자 형식이거나, 상수(const)인 경우는 반드시 생성자 초기화 리스트 초기화해야 한다.

따라서 아래의 코드는 컴파일 에러가 난다.

public:
	const int value1;
	int value2;

	TEST(int val1, int val2)
	{
		value1 = val1; // error
		value2 = val2;
		cout << "생성자 호출 2" << endl;
	}

 

생성자 초기화 리스트를 이용하면 const도 초기에 정의할 수 있다.

public:
	const int value1;
	int value2;

	TEST(int val1, int val2) 
		: value1(val1), value2(val2)
	{
		cout << "생성자 호출 2" << endl;
	}

	void printValue()
	{
		cout << value1 << ", " << value2 << endl;
	}

 

value1을 3으로 초기화하였고, 상수 타입이므로 아래와 같이 5로 변경하는 것은 컴파일 에러가 난다.

int main(void)
{
	TEST test = TEST(3, 4);
	
	test.printValue();
	test.value1 = 5; // error

	return 0;
}

 

참조자의 경우는 아래와 같이 수정한다.

또한 parameter도 참조자를 넘겨받도록 수정한다. (int& val2)

public:
	const int value1;
	int& value2;

	//TEST() : value1(1), value2(2) // 참조자에서 사용 불가
	//{
	//	cout << "생성자 호출" << endl;
	//}

	TEST(int val1, int& val2) 
		: value1(val1), value2(val2)
	{
		cout << "생성자 호출 2" << endl;
	}

 

아래의 main을 실행하고 결과를 보자.

test의 value2가 main의 value2를 참조하고 있다.

따라서 main에서 값을 변경하면 test의 value2도 변경된다. 반대도 마찬가지다.

int main(void)
{
	int value2 = 5;
	TEST test = TEST(3, value2);
	
	test.printValue();

	value2 = 7;
	test.printValue();

	test.value2 = 10;
	test.printValue();
	printf("main value2 : %d\n", value2);

	return 0;
}

 

최종 코드는 아래와 같다.

#include <stdio.h>
#include <iostream>

using namespace std;

class TEST
{
public:
	const int value1;
	int& value2;

	//TEST() : value1(1), value2(2) // 참조자에서 사용 불가
	//{
	//	cout << "생성자 호출" << endl;
	//}

	TEST(int val1, int& val2) 
		: value1(val1), value2(val2)
	{
		cout << "생성자 호출 2" << endl;
	}

	void printValue()
	{
		cout << value1 << ", " << value2 << endl;
	}
};

int main(void)
{
	int value2 = 5;
	TEST test = TEST(3, value2);
	
	test.printValue();

	value2 = 7;
	test.printValue();

	test.value2 = 10;
	test.printValue();
	printf("main value2 : %d\n", value2);

	return 0;
}
반응형

댓글