[C++]클래스의 기본 - C++에서의 구조체(3-1)

10477 단어 윤성우CC

구조체의 등장 배경은 무엇인가?

C언어로 프로그램을 구현한다면 구조체는 항상!!! 무적권!
따르기 마련이다(거진 ㅇㅇ!)
그렇다면 구조체의 이점이 무엇이기에 그런가?

대부분의 프로그래머들은 이렇게 대답할것이다.

"연관 있는 데이터를 하나로 묶으면, 프로그램 구현 및 관리가 용이하다."

소프트웨어를 단순히 표현허묜

"소프트웨어 = 데이터표현 + 데이터 처리"

이다.
그런데 표현해야 하는 데이터는 항상 부류를 형성하기 마련이므로 구조체는 연관 있는 데이터를 묶을 수 있는 문법적 장치로 데이터 표현에 매우 큰 도움을 준다!!

이 구조체를 기반으로 간단한 예제를 보고 가자.

그전에!!!

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

기존에 C에서와 다르게 C++에서는 구조체 변수의 선언을 하기 더 수월하다.

이렇듯 typedef선언은이 불필요하기 때문이다.
그럼 예제를 한번 보자

 #include <iostream>
using namespace std;

#define ID_LEN 20
#define MAX_SPD 200
#define FULE_STEP 2
#define ACC_STEP 10
#define BRK_STEP 10

struct Car
{
    char gameID[ID_LEN]; // ID
    int fuelGauge; // 연료량
    int curSpeed; //현재 속도
};

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

void Accel(Car &car)
{
    if(car.fuelGauge<=0)
        return;
    else
        car.fuelGauge==FULE_STEP;
    
    if ((car.curSpeed+ACC_STEP>=MAX_SPD)) {
        car.curSpeed=MAX_SPD;
        return;
    }
    
    car.curSpeed+=ACC_STEP;
}

void Break(Car &car)
{
    if(car.curSpeed<BRK_STEP)
    {
        car.curSpeed=0;
        return;
    }
    
    car.curSpeed = BRK_STEP;
}

int main(void)
{
    Car run99={"run99",100,0};
    Accel(run99);
    Accel(run99);
    ShowCarState(run99);
    Break(run99);
    ShowCarState(run99);
    
    Car sped77 = {"sped77",100,0};
    Accel(sped77);
    Break(sped77);
    ShowCarState(sped77);
    return 0;
}

짠 !

함수는 결국 데이터의 처리를 담당하는 도구이니, 데이터와 함께 부류를 형성하는것은 매우 당연하다.

따라서 위의 세 함수를 이렇게 말할 수 있다.

"구조체 Car와 함께 부류를 형성하여, Car와 관련된 데이터의 처리를 담당하는 함수들이다."

따라서 위의 함수들은 Car에 종속적인 함수이지만..!
전역함수의 형태를 뛰어서 Car에 종속적임을 나타내지 못하고있다.
이로 인해 다른 영역에서 이 함수를 호출하는 실수를 범할 수 있다.

구조체 안에 함수 삽입하기

c++에서는 구조체안에 함수를 삽입하는것을 허용한다!!
한번 넣어보자 !

이렇듯 함께 선언된 변수에는 직접~! 접근이 가능하다.
그리고 이를 구조체가 아닌 클래스라고 부른다.

이런 형태로 구조체 변수가 생성된다고 생각하면된다.

위 그림을 보면 함수가 각각 별도로 존재하는 것처럼 보이지만 실제로는 모든 Car 구조체 변수가 하나의 함수를 공유한다!

다만 논리적으로 각각의 변수가 자신의 함수를 별도로 지니는 것과 같은 효과 및 결과를 보이기 때문에 C++의 구조체 변수는 저렇게 띤다!!!

그럼 구조체를 클라스로 만든 예제를 보자 !!

#include <iostream>
using namespace std;

#define ID_LEN 20
#define MAX_SPD 200
#define FULE_STEP 2
#define ACC_STEP 10
#define BRK_STEP 10

struct Car
{
    char gameID[ID_LEN]; // ID
    int fuelGauge; // 연료량
    int curSpeed; //현재 속도
    
    void ShowCarState()
    {
        cout<<"소유자 ID"<<gameID<<endl;
        cout<<"연료량 : "<<fuelGauge<<endl;
        cout<<"현재 속도 : "<<curSpeed<<"Km/s"<<endl<<endl;
        
    }
    void Accel()
    {
        if(fuelGauge<=0)
            return;
        else
            fuelGauge-=FULE_STEP;
        
        if ((curSpeed+ACC_STEP>=MAX_SPD)) {
            curSpeed=MAX_SPD;
            return;
        }
        
        curSpeed+=ACC_STEP;
    }
    
    void Break()
    {
        if(curSpeed<BRK_STEP)
        {
            curSpeed=0;
            return;
        }
        
        curSpeed = BRK_STEP;
    }
};







int main(void)
{
    Car run99={"run99",100,0};
    run99.Accel();
    run99.Accel();
    run99.ShowCarState();
    run99.Break();
    run99.ShowCarState();
    
    Car sped77 = {"sped77",100,0};
    sped77.Accel();
    sped77.Break();
    sped77.ShowCarState();
    return 0;
}

이 처럼 구조체 내에 함수가 정의되었기 때문에, 구조체 변수를 대상으로 함수의 호출이 이뤄져야 한다.


문제 03-1

2차원 평면상에서의 좌표 구조체는

struct Point
{
	int xpos;
    	int ypos;
};

위의 구조체를 기반으로 다음의 함수를 정의하고자 한다

void MovePos(int x,int y);	// 점의 좌표이동
void AddPoint(const Point &pos);	// 점의 좌표증가
void ShowPosition();	// 현재 x,y 좌표정보 출력 

단! 위의 함수들을 구조체 안에 정의해서 다음의 형태로 main함수를 구성해야한다.

#include <iostream>
using namespace std;

struct Point
{
    int xpos;
    int ypos;
    
    void MovePos(int x, int y) // 점의 좌표이동
    {
        xpos += x;
        ypos += y;
    }
    
    void AddPoint(const Point &pos) // 점의 좌표증가
    {
        xpos += pos.xpos;
        ypos += pos.ypos;
        
    }
    void ShowPosition() // 현재 x,y좌표 출력
    {
        cout<<"["<<xpos<<","<<ypos<<"]"<<endl;
        
    }
};

int main(void)
{
    Point pos1 = {12,4};
    Point pos2 = {20,30};
    
    pos1.MovePos(-7, 10);
    pos1.ShowPosition(); // 5,14
    
    pos1.AddPoint(pos2);
    pos1.ShowPosition(); // 25 44
    return 0;
}


모얌...
쉽자남...
그냥 직접 접근하면된다.

구조체 안에 enum 상수의 선언

아까 메크로 상수들을 봤는가?

이는 Car구조체에게만 의미 있는 상수이기에
이를 Car클래스 안으로 넣어도 된다.

이런식으로 말이다!!!!

이것이 부담스럽다면 이름공간을 활용하는 방법도있다.

이런 방식으로 말이다.

이런식으로 하면 CAR_CONST만 봐도 이 상수가 어느 영역에서 선언되고 사용되는 상수인지 쉽게 알 수있게 되어가독성이 좋아졌다.

그런데..
이렇게 구조체 안에 다 넣버리면 구조체가 너무 커져버린다
그래서 !!!

함수는 외부로 뺄 수 있다.

함수가 포함되어 있는 C++의 클래스를 보는 순간 다음의 정보들이 쉽게 눈에 들어와야지 좋다

  • 선언되어 있는 변수정보
  • 정의되어 있는 함수정보

보통 프로그램을 분석할때 흐름 및 골격 위주로 분석하기에 함수의 기능만 파악하지 세부구현까지 신경쓰진 않는다.
따라서 구조체를 보는 순간 정의되어 있는 함수의 종류와 기능이 한눈에 들어오게끔 코드를 작성하는 것이 좋다.

그렇기에 구조체내의 함수의 수가 많거나 그 길이가 길다면 다음과 같이 구조체 밖으로 함수를 빼내야 한다!!!


이렇듯
함수의 원형 선언은 구조체 안에두고, 함수의 정의를 구조체 밖으로 빼내는 것이다!!!

다만!
빼낸 다음 해당 함수가 어디에 정의 되어 있는지 정보만 추가해주면 된다.

그러면 이러한 형태의 예제를 보여주고
챕터 3-1을 마치겠다.

#include <iostream>
using namespace std;

namespace CAR_CONST
{
    enum
    {
        ID_LEN = 20,
        MAX_SPD = 200,
        FULE_STEP = 2,
        ACC_STEP = 10,
        BRK_STEP = 10
    };
}


struct Car
{
    char gamerID[CAR_CONST::ID_LEN];
    int fuelGauge;
    int curSpeed;
    
    void ShowCarState(); // 상태 정보 출력
    void Accel(); // 엑셀, 속도 증가
    void Break(); // 브레이크, 속도 감소
};

void Car::ShowCarState()
{
    cout<<"소유자 ID : "<<gamerID<<endl;
    cout<<"연료량 : "<<fuelGauge<<"%"<<endl;
    cout<<"현재속도 : "<<curSpeed<<"Km/s"<<endl<<endl;
}
void Car::Accel()
{
    if(fuelGauge<=0)
        return;
    else
        fuelGauge -= CAR_CONST::FULE_STEP;
    
    if((curSpeed+CAR_CONST::ACC_STEP)>=CAR_CONST::MAX_SPD)
    {
        curSpeed=CAR_CONST::MAX_SPD;
        return;
    }
    
    curSpeed+=CAR_CONST::ACC_STEP;
}

void Car::Break()
{
    if(curSpeed<CAR_CONST::BRK_STEP)
    {
        curSpeed=0;
        return;
    }
    curSpeed-=CAR_CONST::BRK_STEP;
}

int main(void)
{
    Car run99={"run99",100,0};
    run99.Accel();
    run99.ShowCarState();
    run99.Break();
    run99.ShowCarState();
    return 0;
}


구조체 안에 함수가 정의되어 있으면

"함수를 인라인으로처리해라"
인데!!!

구조체에서 함수를빼내면 이 의미가 사라지므로
정의에서 앞에 inline을 이용해서 인라인 처리를 명시적으로 지시해야한다.

이제 다음 부터 본격적으로 클래스에대해 배워보자.

좋은 웹페이지 즐겨찾기