초기화는 클래스의 멤버 변수를 선언과 동시에 적절한 값으로 설정하는 과정을 의미합니다.
C++에서는 다양한 초기화 방법이 존재하며, 초기화를 적절히 수행하지 않으면 쓰레기 값(Garbage Value)이 들어갈 수 있습니다.
버그 예방
메모리 안정성 확보
코드의 유지보수성과 가독성 향상
초기화는 여러 방식으로 수행할 수 있습니다.
생성자 내부에서 초기화
class Knight {
public:
Knight() { _hp = 100; } // 생성자 내부에서 초기화
public:
int _hp;
};
초기화 리스트 (Initializer List)
class Knight {
public:
Knight() : _hp(100) {} // 초기화 리스트를 이용한 초기화
public:
int _hp;
};
const 타입 등)는 반드시 초기화 리스트를 사용해야 합니다.C++11 문법을 사용한 초기화
class Knight {
public:
int _hp = 100; // C++11 이후 문법
};
초기화 리스트는 다음과 같은 상황에서 필수적으로 사용됩니다.
상속 관계에서 부모 클래스의 특정 생성자를 호출해야 할 때
class Player {
public:
Player(int id) { cout << "Player(int id)" << endl; }
};
class Knight : public Player {
public:
Knight() : Player(1) {} // 부모 클래스 생성자를 호출
};
Player(1)을 호출하려면 반드시 초기화 리스트를 사용해야 합니다.참조(Reference) 멤버 변수 초기화
class Knight {
public:
Knight(int& hp) : _hpRef(hp) {} // 초기화 리스트 필요
public:
int& _hpRef; // 참조는 선언과 동시에 초기화되어야 함
};
const 멤버 변수 초기화
class Knight {
public:
Knight() : _hpConst(100) {} // 초기화 리스트 필요
public:
const int _hpConst;
};
const 변수는 초기화 이후 변경이 불가능하기 때문에 초기화 리스트로 설정해야 합니다.클래스 멤버가 또 다른 객체를 포함할 때
class Inventory {
public:
Inventory(int size) { cout << "Inventory(int size)" << endl; }
};
class Knight {
public:
Knight() : _inventory(20) {} // 초기화 리스트 사용
private:
Inventory _inventory;
};
_inventory(20)을 통해 생성자에서 직접 초기화할 수 있습니다.#include <iostream>
using namespace std;
class Inventory {
public:
Inventory() { cout << "Inventory()" << endl; }
Inventory(int size) { cout << "Inventory(int size)" << endl; _size = size; }
~Inventory() { cout << "~Inventory()" << endl; }
public:
int _size = 10;
};
class Player {
public:
Player() {}
Player(int id) { cout << "Player(int id)" << endl; }
};
// Knight는 Player를 상속받음 (Is-A 관계)
class Knight : public Player {
public:
// 초기화 리스트 사용
Knight() : Player(1), _hp(100), _inventory(20), _hpRef(_hp), _hpConst(100) {
cout << "Knight()" << endl;
}
public:
int _hp; // 초기화되지 않으면 쓰레기 값이 들어감
Inventory _inventory; // 포함 관계 (Has-A)
int& _hpRef; // 참조 타입 (초기화 리스트 필요)
const int _hpConst; // const 변수 (초기화 리스트 필요)
};
int main() {
Knight k;
cout << "Knight의 HP: " << k._hp << endl;
if (k._hp < 0) {
cout << "Knight is Dead" << endl;
}
return 0;
}
Player(int id)
Inventory(int size)
Knight()
Knight의 HP: 100
~Inventory()
Knight k; 객체가 생성되면서Player(1) 호출Inventory(20) 호출Knight() 생성자 실행~Inventory()가 호출됨.