Player0.h - 기본 생성자와 오버로딩된 생성자

#pragma once
#include <iostream>

using namespace std;

class Player0
{
private:
    int _health;
    int _power;

public:
    Player0()
    {
        // 디폴트 생성자(파라메터가 한 개도 없는 생성자)
        // 한 개의 생성자도 주어지지 않는다면 컴파일러가 암시적으로 만들어준다
        _health = 100;
        _power = 50;
        cout << "Player " << _health << ", " << _power << endl;
    }
    Player0(int health, int power)
    {
        _health = health;
        _power = power;

        cout << "Player " << _health << ", " << _power << endl;
    }
};

void player0()
{
    Player0 player0(100, 50);
    Player0 player1 = Player0(300, 150);
    Player0* player2 = new Player0(400, 250);

    Player0 player3;
    Player0 player4 = Player0();
    Player0* player5 = new Player0();
}

분석:

  • Player0 클래스는 두 개의 생성자를 가집니다. 하나는 기본 생성자이며, 다른 하나는 두 개의 인자를 받는 생성자입니다.
  • 기본 생성자: 매개변수가 없는 생성자로, _health를 100, _power를 50으로 초기화합니다.
  • 오버로딩된 생성자: healthpower라는 두 개의 인자를 받아서 _health_power를 초기화합니다.
  • player0 함수에서는 다양한 방법으로 Player0 객체를 생성합니다.
    • Player0 player0(100, 50);는 오버로딩된 생성자를 사용하여 객체를 생성합니다.
    • Player0 player3;는 기본 생성자를 사용하여 객체를 생성합니다.

Player1.h - 기본 인자(Default Parameters)를 활용한 생성자

#pragma once
#include <iostream>

using namespace std;

class Player1
{
private:
    int _health;
    int _power;

public:
    Player1(int health = 100, int power = 50) // 디폴트 파라메터를 이용하여 중복 제거
    {
        _health = health;
        _power = power;

        cout << "Player " << _health << ", " << _power << endl;
    }
};

void player1()
{
    Player1 player0(100, 50);
    Player1 player1 = Player1(300, 150);
    Player1* player2 = new Player1(400, 250);

    Player1 player3;
    Player1 player4 = Player1();
    Player1* player5 = new Player1();

    Player1 player6(300); // health만으로 초기화 될 수 있음
}

분석:

  • Player1 클래스는 생성자 오버로딩 대신 디폴트 파라메터를 사용하여 중복을 제거합니다.
  • healthpower에 기본값을 제공함으로써, 생성자 하나만으로 다양한 초기화를 수행할 수 있습니다.
  • player1 함수에서는 Player1 객체를 생성하는 다양한 방법을 보여줍니다.
    • Player1 player6(300);_health는 300으로, _power는 기본값 50으로 초기화됩니다.

Player2.h - 잘못된 초기화 시도

#pragma once
#include <iostream>

using namespace std;

class Player2
{
private:
    int _health;
    int _power;

public:
    Player2()
    {
        // 중복 제거를 위해 Player2(int, int)를 호출한 듯 보이지만 실제로는 Player2를 한 번 더 생성
        Player2(100, 50); 
    }
    Player2(int health, int power)
    {
        _health = health;
        _power = power;

        cout << "Player " << _health << ", " << _power << endl;
    }

    void print()
    {
        cout << _health << endl;
        cout << _power << endl;
    }
};

void player2()
{
    Player2 player;
    player.print();
}

분석:

  • Player2 클래스의 기본 생성자는 잘못된 방식으로 다른 생성자를 호출하려고 시도합니다.
  • Player2(100, 50); 호출은 새로운 Player2 객체를 생성하지만, 이 객체는 즉시 파괴되고, 실제로 _health_power를 초기화하지 않습니다.
  • player2 함수에서 Player2 객체를 생성하고, print() 메서드를 호출하면 _health_power가 초기화되지 않은 값을 출력할 가능성이 있습니다.

Player3.h - 위임 생성자(Delegating Constructor)

#pragma once
#include <iostream>

using namespace std;

class Player3
{
private:
    int _health;
    int _power;

public:
    Player3() : Player3(100, 50) // 위임 생성자
    {
    }
    Player3(int health, int power)
    {
        _health = health;
        _power = power;

        cout << "Player " << _health << ", " << _power << endl;
    }

    void print()
    {
        cout << _health << endl;
        cout << _power << endl;
    }
};

void player3()
{
    Player3 player;
    player.print();
}

분석:

  • Player3 클래스는 위임 생성자를 사용하여 기본 생성자가 다른 생성자에게 초기화를 위임합니다.
  • Player3() 기본 생성자는 Player3(100, 50) 생성자를 호출하여 _health_power를 초기화합니다.
  • player3 함수에서 Player3 객체를 생성하고 print()를 호출하면 올바르게 초기화된 값을 출력합니다.

Player4.h - 멤버 초기화 리스트(Member Initialization List)와 상수 멤버 초기화

#pragma once
#include <iostream>
#include <string>

using namespace std;

class Player4
{
private:
    int _health;
    int _power;
    const string _name;

public:
    Player4() : Player4(100, 50, "noname") 
    {
    }
    Player4(int health, int power, string name)
        : _health(health), _power(power), _name(name) // 멤버 초기화 리스트, 초기화 순서는 클래스에 선언된 순서
    {
        cout << "Player " << _health << ", " << _power << endl;
    }

    void print()
    {
        cout << _name << endl;
        cout << _health << endl;
        cout << _power << endl;
    }
};

void player4()
{
    Player4 player;
    player.print();
}

분석:

  • Player4 클래스는 멤버 초기화 리스트를 사용하여 멤버 변수를 초기화합니다.
  • const string _name은 반드시 멤버 초기화 리스트에서 초기화해야 합니다.
  • _health, _power, _name은 멤버 초기화 리스트를 통해 초기화되며, 생성자 본문에서 불필요한 대입이 발생하지 않습니다.
  • player4 함수에서 생성된 객체는 올바르게 초기화되어 print() 메서드로 출력할 때 예상된 값을 보여줍니다.

Player5.h - 인라인 초기화와 컴파일러 기본 생성자 사용

#pragma once
#include <iostream>
#include <string>

using namespace std;

class Player5
{
private:
    // 인라인 초기화
    int _health = 100;
    int _power = 50;
    const string _name = "noname";

public:
    Player5() = default; // 컴파일러가 만든 생성자를 사용하겠다는 것을 명시
    //Player5() = delete; // 컴파일러가 생성자를 암시적으로 만들지 말 것을 명시
    Player5(int health, int power, string name)
        : _health(health), _power(power), _name(name)
    {

        cout << "Player " << _health << ", " << _power << endl;
    }

    void print()
    {
        cout << _name << endl;
        cout << _health << endl;
        cout << _power << endl;
    }
};

void player5()
{
    Player5 player;
    player.print();
}

분석:

  • Player5 클래스는 인라인 초기화를 통해 멤버 변수의 기본값을 제공합니다.
  • Player5() 기본 생성자는 = default 키워드를 사용하여 컴파일러가 기본 생성자를 생성하도록 명시합니다.
  • player5 함수에서 생성된 객체

는 기본 생성자 또는 오버로딩된 생성자로 생성되어, 인라인 초기화된 값 또는 전달된 값으로 초기화됩니다.

main.cpp - 모든 예제의 실행

#include <iostream>
#include "Player0.h"
#include "Player1.h"
#include "Player2.h"
#include "Player3.h"
#include "Player4.h"
#include "Player5.h"

using namespace std;

int main()
{
    player0();
    player1();
    player2();
    player3();
    player4();
    player5();
}

분석:

  • main 함수는 각각의 player0부터 player5까지의 함수를 호출하여 각 클래스를 테스트합니다.
  • 각 함수는 해당 클래스의 객체를 생성하고, 생성자 및 소멸자가 올바르게 작동하는지, 그리고 객체가 올바르게 초기화되는지 확인합니다.

결론

이 예제 코드를 통해 C++에서 생성자를 활용하는 다양한 방법을 배울 수 있습니다. 생성자 오버로딩, 기본 인자, 위임 생성자, 멤버 초기화 리스트, 인라인 초기화, 그리고 컴파일러 생성자 명시 등은 모두 코드의 가독성, 효율성, 유지보수성을 높이는 데 중요한 역할을 합니다. 이러한 기술들을 이해하고 적절히 활용하는 것은 C++ 프로그래밍에서 매우 중요합니다.

profile
李家네_공부방

0개의 댓글