[c++] c++ 클래스의 기본



구조체클래스에 관한 공부 내용을 다루고 있다.

윤성우의 열혈 C++ 교재를 바탕으로 작성되었다.

  • 목차
    • CPP에서의 구조체
      • C++에서의 구조체 변수의 선언
      • 구조체 안에 함수 삽입하기
      • 구조체 안에 enum 상수의 선언
      • 함수는 외부로 뺄 수 있다.
    • 클래스와 객체
      • 클래스와 구조체의 유일한 차이점
      • 접근제어 지시자(접근제어 레이블)
      • 용어정리: 객체(Object), 멤버변수, 멤버함수
      • C++에서의 파일분할
      • 인라인 함수는 헤더파일에 함께 넣어야 한다.
    • 객체지향 프로그래밍의 이해
      • 객체지향 프로그래밍의 이해
      • 객체를 이루는 것은 데이터와 기능
      • 멤버변수의 상수화에 대한 논의
      • ‘나(me)’를 표현하는 클래스의 정의
      • 클래스 기반의 두 가지 객체생성 방법
      • 객체간의 대화 방법(Message Passing 방법)

CPP에서의 구조체


📌 C++에서의 구조체 변수의 선언

C언어에서의 구조체 변수를 선언하는 법은 아래와 같다.

struct Car basicCar;
struct Car simpleCar;

​ 💡 struct를 생략하려면 typedef선언을 추가해야 한다.

​ 하지만, C++에서는 별도의 typedef 선언 없이도 다음과 같이 변수를 선언할 수 있다.

Car basicCar;
Car SimpleCar;
📌 구조체 안에 함수 삽입하기
  1. 구조체 바깥에 함수가 있는 경우.

    매개변수를 통해서 연산의 대상 정보를 전달받고 함수 내에서도 참조자 car를 대상으로 연산(출력)한다.

    void ShowCarState(const Car &car)
    {
        cout<<"소유자ID" <<car.gamerID<<endl;
        cout<<"연료량: " <<car.fuleGauge<<"%"<<endl;
        cout<<"현재속도: " <<car.curSpeed<<"km/s"<<endl<<endl;
    }
    

​ 🔎 <<연산자를 이용한std::endl 의 출력은 개행으로 이어진다.

  1. 구조체 안에 함수가 삽입된 경우.

    함수가 구조체 내에 삽입되면서 구조체 내에서 선언된 변수에 직접접근이 가능해져서 연산의 대상에 대한 정보가 불필요하다.

    void ShowCarState()
    {
        cout<<"소유자ID" <<gamerID<<endl;
        cout<<"연료량: " <<fuleGauge<<"%"<<endl;
        cout<<"현재속도: " <<curSpeed<<"km/s"<<endl<<endl;
    }
    
📌 구조체 안에 enum 상수의 선언

​ 보통 상수를 선언 할 때 다음과 같이 코드를 작성한다.

   ```C++
   #define ID_LEN    20
   #define MAX_SPD   200
   #define FUEL_STEP 2
   #define ACC_STEP  10
   #define BRK_STEP  10
   ```

​ 하지만 이 상수들이 어떠한 구조체에게만 의미가 있다면, 상수들도 구조체 내에 포함시키는 것이 좋을 수 있다. (✔무조건 좋다는 것은 아님!)

    ```C++
    struct Car
    {
        enum
        {
            ID_LEN  =20,
            MAX_SPD =200,
            FUEL_STEP =2,
            ACC_STRP  =10,
            BRK_STEP  =10
        };
        
        char gamerID[ID_LEN];
        int fuelGauge;
        int curSpeed;
        
        void ShowCarState(){...}
        int Accel(){...}
        void Break(){...}
    };
    ```

💡enum의 선언을 구조체 내부에 삽입하는 방법이 부담스럽다면, 이름공간을 이용해서 상수가 사용되는 영역을 명시할 수 있다.

#include <iostream>
using namespace std;

namespace CAR_CONST
{
    enum
    {
        ID_LEN  =20,
        MAX_SPD =200,
        FUEL_STEP =2,
        ACC_STRP  =10,
        BRK_STEP  =10
    };
}

struct Car
{
    char gamerID[CAR_CONST::ID_LEN];
    int fuelGauge;
    int carSpeed;
    
    void ShowCarState(){...}
    int Accel()
    {
        if(fuelGauge<=0)
            return;
        else
            fuelGauge -= CAR_CONST::FUEL_STEP;
        
        if((curSpeed+CAR_CONST::ACC_STEP)>=CAR_CONST::MAX_SPD)
        {
            curSpeed=CAR_CONST::MAX_SPD;
            return;
        }
        curSpeed += CAR_CONST::ACC_STEP;
    }
    void Break(){...}
};

😊 이름공간을 지정해서 코드를 작성했기 때문에, 문장만 봐도 이 상수가 어느 영역에서 선언되고 사용되는 상수인지 쉽게 알 수 있다. 따라서 가독성이 좋아졌다고 할 수 있다.

📌 함수는 외부로 뺄 수 있다.

​ 함수가 포함되어 있는 구조체를 보는 순간, 다음의 정보들이 쉽게 눈에 들어와야 코드의 분석이 용이하다.

​ 👉 선언되어 있는 변수정보

​ 👉 정의되어 있는 함수정보

​ 구조체 내에 정의된 함수의 수가 많거나 그 길이가 길다면, 다음과 같이 구조체 밖으로 함수를 빼낼 필요가 있다.

```C++
struct Car
{
    .....
    void ShoeCarState();
    void Accel();
    ....
};

void Car::ShowCarState()
{
    .....
}
void Car::Accel()
{
    .....
}
```

💡 함수의 원형선언을 구조체 안에 두고, 함수의 정의를 구조체 밖으로 빼내는 것이다.

클래스와 객체


📌 클래스와 구조체의 유일한 차이점

​ 키워드 struct를 대신해서 class를 사용하면, 구조체가 아닌 클래스가 된다. 즉, 아래의 코드는 클래스의 정의이다.

class Car
{
    char gamerID[CAR_CONST::ID_LEN];
    int fuelGauge;
    int curSpeed;
    
    void ShowCarState(){....}
    void Accel(){....}
    void Break(){....}
};

하지만 키워드를 바꾸면 구조체처럼 변수를 선언하지 못한다.

Car run99={"run99",100,0}; //(x)
//클래스 내에서 선언된 함수가 아닌, 다른 영역에서 변수를 초기화 하려고 했기 때문에 불가능하다.
//클래스 내에 선언된 변수는 클래스 내에 선언된 함수에서만 접근이 가능하다.
Car run00; //(0)

클래스를 정의하는 과정에서 각각의 변수 및 함수의 접근 허용범위를 별도로 선언해야 한다.

이것이 키워드 struct를 이용해서 정의하는 구조체와 키워드 class를 이용해서 정의하는 클래스의 유일한 차이점이다.

📌 접근제어 지시자(접근제어 레이블)

​ 👉 public 어디서든 접근허용

​ 👉 protected 상속관계에 놓여있을 때, 유도 클래스에서의 접근허용

​ 👉 private 클래스 내(클래스 내에 정의된 함수)에서만 접근허용

📌 용어정리: 객체(Object), 멤버변수, 멤버함수
  • 객체

  • 멤버변수 : 클래스를 구성하는(클래스 내에 선언된) 변수

    char gamerID[CAR_CONST::ID_LEN];
    int fuelGauge;
    int curSpeed;
    
    • 멤버함수 : 클래스를 구성하는(클래스 내에 정의된) 함수
       void InitMembers(char * ID, int fuel);
       void ShowCarState();
       void Accel();
       void Break();
    

📌 C++에서의 파일분할

  • Car.h 클래스의 선언을 담는다.

  • Car.cpp 클래스의 정의(멤버함수의 정의)를 담는다.

📌 인라인 함수는 헤더파일에 함께 넣어야 한다.

인라인 함수의 호출문장은 컴파일러에 의해서 인라인 함수의 몸체로 대체 되어야 한다.

때문에 인라인 함수는 클래스의 선언과 동일한 파일에 저장되어서 컴파일러가 동시에 참조할 수 있게 해야 한다.

객체지향 프로그래밍의 이해


📌 객체지향 프로그래밍의 이해

객체지향 프로그래밍은 현실에 존재하는 사물과 대상, 그리고 그에 따른 행동을 있는 그대로 실체화시키는 형태의 프로그래밍이다.

📌 객체를 이루는 것은 데이터와 기능

  • 행동(behavior)과 상태(state)

객체는 하나 이상의 상태 정보(데이터)와 하나 이상의 행동(기능)으로 구성된다.

📌 멤버변수의 상수화에 대한 논의

​ 아래와 같이 클래스의 멤버변수 선언문에서 초기화까지 하는 것은 불가능하다.

const int APPLE_PRICE=1000; //(X)

🔎 이 문제는 클래스의 상속 챕터의 생성자로 해결할 수 있다.

📌 나(me)를 표현하는 클래스의 정의

  • 클래스는 아무런 선언이 존재하지 않을 때 private으로 간주된다.구조체는 public

📌 클래스 기반의 두 가지 객체생성 방법

ClassName objname;   //일반적인 변수의 선언방식
ClassName * ptrObj=new ClassName; //동적 할당방식(힙 할당방식)

📌 객체간의 대화 방법(Message Passing 방법)

하나의 객체가 다른 하나의 객체에게 메세지를 전달하는 방법은 함수호출을 기반으로 한다. 그래서 객체지향에서는 이러한 형태의 함수호출을 가리켜 메세지전달(Message Passing)이라 한다.




© 2021.08. by Yeram522

Powered by theorydb