[C++] #3 생성자 (Constructor)

    반응형

    #2 [C++] getter setter 함수 편에서 getter setter 함수를 이용해 private로 선언된 클래스의 멤버에 접근하는 방법에 대해서 소개했다.

    하지만 아래 코드처럼 유니폼 초기화 (Uniform Initialization) 방식을 사용하지 못하고, public 필드에 선언된 함수를 이용해 우회해서 private멤버를 초기화 해야 하기에 코드도 길어지고 불편하다.

    Player warrior {"Warrior", 10, 100, 10, 20};

    이번 포스팅 에서는 이러한 불편함을 해소할 수 있는 생성자(Constructor) 문법에 대해서 정리해 보고자 한다. 

     

    * 개인적인 공부 내용을 기록하는 용도로 작성한 글 이기에 잘못된 내용을 포함하고 있을 수 있습니다.

     

    #1 생성자 _ Constructor

    #2 생성자 오버로딩 _ Constructor Overloading

    #3 기본 생성자 _ Default Constructor


    #1 생성자 _ Constructor

    생성자란 객체 생성과 동시에 호출되는 특수한 멤버함수이다. 생성자를 이용하면 보다 편리하게 객체의 멤버를 초기화 할 수 있다.

    생성자의 선언 규칙은 다음과 같다.

    1. 생성자의 이름은 클래스의 이름과 동일해야 한다.

    2. 생성자는 반환값을 가지지 않는다.

    class 클래스명{
    	// 생성자(Constructor)
    	클래스명() {
    	}
    };

     

    다음은 생성자를 이용해 Player 객체의 private 필드 멤버변수를 할당한 예제이다.

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Player {
    private:
    	string m_name;
    	int m_level;
    	int m_hp;
    	int m_mp;
    	int m_atk;
    public:
    	// 생성자 Constructor
    	// 생성자를 이용해 private 멤버를 초기화
    	Player() {
    		m_name = "Player";
    		m_level = 10;
    		m_hp = 100;
    		m_mp = 10;
    		m_atk =10;
    	}
    
    	// void setInfo(string name, int level, int hp, int mp, int atk)
    	// {
    	// 	m_name = name;
    	// 	m_level = level;
    	// 	m_hp = hp;
    	// 	m_mp = mp;
    	// 	m_atk = atk;
    	// }
    	
    	void getInfo()
    	{
    		cout << "==== PRINT INFO ====" << endl;
    		cout << "name : " << m_name << endl;
    		cout << "level : " << m_level << endl;
    		cout << "hp : " << m_hp << endl;
    		cout << "mp : " << m_mp << endl;
    		cout << "atk : " << m_atk << endl;
    	}
    };
    
    int main() {
    	Player warrior;
    	warrior.getInfo();
    	return 0;
    }
    ==== PRINT INFO ====
    name : Player
    level : 10
    hp : 100
    mp : 10
    atk : 10

     

    #2 생성자 오버로딩 _ Constructor Overloading

    생성자 또한 함수이기에, 파라미터를 설정할 수 있다. 다음은 생성자를 오버로딩하여 매개변수가 존재하는 생성자를 선언한 예제 코드이다. 매개변수가 있는 생성자를 사용하면 이전처럼 유니폼 초기화 방식으로 바로 private 멤버에 값을 대입해 줄 수 있다.

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Player {
    private:
    	string m_name;
    	int m_level;
    	int m_hp;
    	int m_mp;
    	int m_atk;
    public:
    	// 생성자 Constructor
    	Player() {
    		m_name = "Player";
    		m_level = 10;
    		m_hp = 100;
    		m_mp = 10;
    		m_atk =10;
    	}
    	
    	// 매개변수가 있는 생성자. _ 함수 오버로딩
    	Player(string name, int level, int hp, int mp, int atk) {
    		m_name = name;
    		m_level = level;
    		m_hp = hp;
    		m_mp = mp;
    		m_atk = atk;
    	}
    	
    	void getInfo()
    	{
    		cout << "==== PRINT INFO ====" << endl;
    		cout << "name : " << m_name << endl;
    		cout << "level : " << m_level << endl;
    		cout << "hp : " << m_hp << endl;
    		cout << "mp : " << m_mp << endl;
    		cout << "atk : " << m_atk << endl;
    	}
    };
    int main() {
    	// 매개변수가 있는 생성자를 이용해 객체를 바로 초기화 한다.
    	Player warrior { "Warrior", 10, 100, 10, 25 };
    	warrior.getInfo();
    	return 0;
    }
    ==== PRINT INFO ====
    name : Warrior
    level : 10
    hp : 100
    mp : 10
    atk : 25

     

    #3 기본 생성자 _ Default Constructor

    사실 모든 클래스 객체는 기본 생성자 (Default Constructor) 를 가지고 있다. 애초에 클래스에는 반드시 생성자가 있어야 하며 객체를 생성할 때 반드시 하나의 생성자가 호출되도록 정해져 있다. 따라서 프로그래머가 따로 생성자를 정의해 주지 않을 때 컴파일러가 자동으로 기본 생성자를 선언해 준다.

    class Player {
    private:
    	string m_name;
    	int m_level;
    	int m_hp;
    	int m_mp;
    	int m_atk;
    public:
    	// 기본 생성자 Default Constructor
    	Player() { }
    };

     

    그러나 생성자를 하나라도 선언했다면, 기본 생성자는 따로 정의되지 않는다. 그렇기에 매개변수가 있는 생성자만을 정의하고, 아래 코드처럼 객체를 생성하면 기본 생성자가 존재하지 않는다는 에러가 발생한다. 

    class Player {
    private:
    	string m_name;
    	int m_level;
    	int m_hp;
    	int m_mp;
    	int m_atk;
    public:
    	// 매개변수가 있는 생성자
    	Player(string name, int level, int hp, int mp, int atk) {
    		m_name = name;
    		m_level = level;
    		m_hp = hp;
    		m_mp = mp;
    		m_atk = atk;
    	}
    };
    
    
    int main() {
    	Player warrior; // 기본 생성자를 찾을 수 없음.
    	return 0;
    }

     

    따라서 기본 생성자는 반드시 하나 이상 정의해 주는 것이 좋다.

    #include <iostream>
    #include <string>
    using namespace std;
    
    class Player {
    private:
    	string m_name;
    	int m_level;
    	int m_hp;
    	int m_mp;
    	int m_atk;
    public:
    	// 기본 생성자
    	Player() {
    		
    	}
    	// 매개변수가 있는 생성자
    	Player(string name, int level, int hp, int mp, int atk) {
    		m_name = name;
    		m_level = level;
    		m_hp = hp;
    		m_mp = mp;
    		m_atk = atk;
    	}
    };
    
    
    int main() {
    	Player warrior;
    	return 0;
    }
    반응형

    댓글

    Designed by JB FACTORY