[C++] 클래스(Class) 사용법 & 예제 총정리

    클래스(Class)란?

    클래스(class)는 객체 지향 프로그래밍(OOP)에서 특정 객체를 생성하기 위해 변수와 메서드를 정의하는 일종의 틀이며 내부적으로 객체를 정의하기 위한 상태 값을 의미하는 멤버 변수와 클래스의 동작인 메서드(함수)로 구성됩니다. 객체 지향 프로그래밍에서는 모든 데이터를 객체(object)로 취급하며 이 객체들의 조합으로 프로그래밍을 하는 방식을 의미합니다. C++에서 클래스(class)란 구조체(struct)의 상위 호환으로 이해할 수 있습니다. 구조체와 다른점은 접근 제어 지시자가 추가되었고 함수를 포함할 수 있게 된 점입니다.

     

    접근 제어 지시자

    지시자 설명
    public 어디서든 접근이 가능 (외부에서도 모두 접근 가능)
    private 클래스 내부에 정의된 함수에서만 접근 허용 (중요한 정보를 감출때 사용)
    protected 기본적으로는 private이지만 상속관계에 놓여있을 때, 유도 클래스에서는 접근 허용

     

     클래스(Class) 사용법 

    클래스 생성

    class 클래스 이름{
    접근 제어 지시자:
        멤버변수:
        멤버함수
    };
    

    C++에서는 클래스를 위와 같은 문법으로 생성합니다.

    class MyCar {
    private:
        //멤버변수
        int fuel = 0;
        bool power = false;
    
    public:
        //메소드
        void go() {
            this->fuel--;
        }
    
        void oiling(int n) {
            this->fuel += n;
        }
    
        void fuel_check() {
            std::cout << "연료 : " << fuel << std::endl;
        }
    };
    

    예를 들자면 위와 같습니다. 여기서 this는 클래스 내의 멤버 변수를 의미합니다. this포인터는 클래스의 실제 인스턴스에 대한 주소를 가리키는 포인터로써 사용해주면 멤버 변수와 같은 이름의 인자값이 들어와도 멤버 변수와 인자 값을 구분 지어질 수 있고 this로 가리키는 변수가 클래스의 멤버 변수라는 것이라는 직관성이 높아집니다.

     

    클래스 생성 및 사용

    MyCar car = MyCar(); //생성
    
    //메서드 호출
    car.oiling(100);
    car.fuel_check();
    for (int i = 0; i < 10; i++) car.go();
    car.fuel_check();
    car.oiling(100);
    for (int i = 0; i < 10; i++) car.go();
    car.fuel_check();
    

    클래스 생성, 사용 예제

    클래스의 생성과 사용은 위와 같이 하시면 됩니다.

     

    클래스 배열 사용

    MyCar car[3]; //생성
    for (int i = 0; i < 3; i++)car[i] = MyCar(); //초기화
    
    //메서드 호출
    car[0].oiling(100);
    car[0].fuel_check();
    for (int i = 0; i < 10; i++) car[0].go();
    car[0].fuel_check();
    

    클래스 배열을 사용할때는 생성 즉시 바로 초기화가 안됩니다. 생성 후 따로 for문을 돌려서 일일이 초기화를 시켜준 뒤 사용하셔야 합니다. 클래스 배열이 생성 후 즉시 초기화가 안되므로 기본 생성자가 클래스 내부에 정의되어 있어야 사용이 가능합니다.

     

    생성자와 소멸자

    생성자와 소멸자는 클래스 객체가 생성 및 소멸될 때 자동으로 호출되는 함수입니다. 생성자 소멸자의 경우 따로 기술하지 않아도 컴파일러가 알아서 만들어서 넣습니다. 단 이렇게 생성된 생성자, 소멸자는 아무런 기능이 없습니다. 반대로 아래와 같이 따로 프로그래머가 만들어줄 수도 있습니다.

    class MyCar {
    private:
        //멤버변수
        int fuel = 0;
        bool power = false;
    
    public:
        //생성자
        MyCar() {
            this->fuel = 100;
            this->power = true;
        }
        //생성자 다중 정의
        MyCar(int n) {
            this->fuel = n;
            this->power = true;
        }
        //소멸자(다중 정의 불가능)
        ~MyCar() {
            std::cout << "소멸되었습니다." << std::endl;
        }
    };
    

    이 두함수의 가장 큰 특징은 함수임에도 불구하고 반환 형식이 없다는 것과 함수 이름이 클래스 이름과 같다는 점입니다. 다만 소멸자의 경우 앞에 ~가 붙습니다. 생성자는 오버로딩을 통한 다중 정의가 가능하고 소멸자의 경우에는 다중 생성이 불가능합니다. 생성자는 객체를 생성할때 호출되고 소멸자는 객체가 생성된 블록이 끝날때 소멸자를 호출 합니다. 생성자와 소멸자 이외에도 객체를 복사할 때 사용되는 복사 생성자, 복사 대입 연산자도 있습니다. 이 또한 생략하면 컴파일러가 자동으로 넣어줍니다. 복사 생성자와 복사 대입 연산자가 궁금하시다면 아래 글을 참고해주세요.

    [C++] 복사 생성자, 복사 대입 연산자 (+깊은 복사)

     

    클래스의 상속

    #include <iostream>
    class MyCar {
    protected: //상속한 클래스 사용가능
        //멤버변수
        int fuel = 0;
        bool power = false;
    
    public:
        //메소드
        void go() {
            this->fuel--;
        }
    
        void oiling(int n) {
            this->fuel += n;
        }
    
        void fuel_check() {
            std::cout << "연료 : " << fuel << std::endl;
        }
    };
    
    class MySuv : public MyCar { // 상속
    public:
        //메소드
        void go() {
            this->fuel-=2;
        }
    };
    
    void main() {
        MySuv car = MySuv(); //MySuv 객체 생성
    
        //메서드 호출
        car.oiling(100);
        car.fuel_check();
        for (int i = 0; i < 10; i++) car.go();
        car.fuel_check();
        car.oiling(100);
        for (int i = 0; i < 10; i++) car.go();
        car.fuel_check();
    }
    

    클래스 상속 예제

    객체를 잘 설계해서 상속을 하면 코드의 재사용성을 높여줍니다. 상속을 받는 방법은  class 파생클래스 이름 : 접근제어 지시자 부모 클래스 이름 이렇게 하시면 됩니다. 위의 예제처럼 객체를 상속받으면 상속한 객체의 특징들을 그대로 사용할 수 있습니다. 단 상속하더라도 private로 사용된 멤버 변수나 메서드는 사용하실 수 없습니다.

    댓글

    Designed by JB FACTORY