17 분 소요

0. 절차지향 프로그래밍 vs 객체지향 프로그래밍

  • 절차지향 프로그래밍(Procedural Programming) : 함수를 중심의 프로그래밍 방법 (c)
  • 객체지향 프로그래밍(Object Oriented Programming) : 객체를 중심으로 돌아가는 프로그래밍 방법 (c++, c#, java …)


1. 클래스와 객체

1.1. 클래스(Class)란?

  • 객체(object)를 정의하는 혹은 설계도
  • 멤버 변수(state) + 멤버 함수(behavior) 으로 구성됨
  • 클래스는 컴파일이 끝나면 사라짐
class Knight
{
    // 생성자와 소멸자
    public:
        Knight();
        ~Knight();

    // 멤버 함수(기능, 동작)
    public:
        void Move(int y, int x);
        void Attack();
        void Die() { /* Die 구현 */ }

    // 멤버 변수(속성, 데이터)
    private:
        int m_hp;
        int m_attack;
        int m_posY;
        int m_posX;
};

void Knight::Move(int y, in x) { m_posY = y; m_posX = x; }
void Knight::Attack() { /* Attack 구현 */ }

1.2. 객체(Object, Instance)란?

  • 주변의 모든 것이 객체
  • 클래스(class)에 의해 만들어짐
  • c++ 프로그램이 실행되는 동안 실존
int main()
{
    // 객체 생성
    Knight k1; 
    // 멤버 변수 설정
    k1.m_hp = 200;
    k1.m_attack = 5;
    k1.m_posY = 0;
    k1.m_posX = 0;
    // 멤버 함수 사용
    k1.Move(5, 5);
    
    return 0;
}


2. 생성자와 소멸자

  • 생성자(Constructor) : 객체가 생성 될 때 실행되는 함수, 1개 이상의 생성자 존재 가능
  • 소멸자(Destructor) : 객체가 소멸 될 때 실행되는 함수, 1개만 존재

2.1. 생성자

1) 암시적(implicit) 생성자 : 생성자를 명시적으로 만들지 않으면 기본 생성자기본 복사 생성자가 자동으로 생성된다.
2) 명시적(Explicit) 생성자 : 사용자가 선언한 생성자(명시적으로 생성하면 암시적 생성은 없음)

  • 기본 생성자

    Knight() // *) 매개변수가 없다
    {
        // TODO: 초기값 설정
    }
    
    Knight k0;
    
  • 복사 생성자

    Knight(const Knight& k) // *) 자신의 클래스를 참조타입 매개변수로 받음
    {
        this.m_hp = k.m_hp;
        this.m_attack = k.m_attack;
        this.m_posY = k.m_posY;
        this.m_posX = k.m_posX;
    }
    
    Knight k1(k0);
    Knight k2 = k0;
        
    // *) 복사 생성자가 아닌 경우!
    Knight k3;
    k3 = k1; // ⚠ 복사 연산자가 호출!
    
  • 기타 생성자

    Knight(int x, int y) // 기본 생성자, 복사 생성자 외
    {
        m_posY = y;
        m_posX = x;
    }
    
    • 타입 변환 생성자

        explicit Knight(int x) {...} // 매개변수를 1개만 받는 생성자
        // *) explicit가 없을 경우, 암시적으로 int 타입의 매개변수를 Knight으로 형변환 한다.
      


3. 멤버변수 초기화 방법

1) 생성자 내에서 초기화

Knight()
{
    m_hp = 200;
    m_attack = 5;
    m_posY = 0;
    m_posX = 0;
}

2) 초기화 리스트

  • 상속관계에서 원하는 부모 생성자 호출 시 사용
  • 멤버타입이 클래스인 경우 성능의 차이가 생김 (일반변수는 차이나지 않음)
  • 정의함과 동시에 초기화가 필요한 경우 사용(참조타입, const타입)
Knight() : m_hp(200), m_attack(5), m_posY(0), m_posX(0) { ... }

3) c++11 문법

class Knight
{
    ...
    private:
        int m_hp = 200;
        int m_attack = 5;
        int m_posY = 0;
        int m_posX = 0;
};

3.1 활용 예시

class Player // 상속관계 클래스
{
    public:
        Player() {...}
        explicit Player(int type) {...}
    private:
        int _type;
};

class Inventory // 포함관계 클래스
{
    public:
        Inventory() {...}
        Inventory(int size) {...}
    private:
        int _size;
};
class Knight : public Player
{
    public:
        // 1) 생성자 내에서 초기화
        Knight() { _inventory = Inventory(20); } // *) 비효율적
        // 2) 초기화리스트를 활용한 객체 초기화
        Knight() : _inventroy(20) {...}
        // 3) 정의함과 동시에 초기화가 필요한 경우
        Knight() : _refHp(_hp), _constHp(100) {...}
    private:
        Inventory _inventory;
        int _hp;
        int& _refHp; // or int& _refHp = hp;
        const int _constHp; // or const int _constHp = 100; 
}


📑. 참고

카테고리:

업데이트:

댓글남기기