본문 바로가기

프로그래밍 언어들/C++

CHAPTER03 - 클래스의 기본

1. C++에서의 구조체

구조체는 연관 있는 데이터를 묶을 수 있는 문법적 장치이다.


(1) C++에서의 구조체 선언

C에서는 구조체를 나타내는 'struct'를 명시해 주어야 한다. 이것을 생략하려면 'typedef' 선언을 추가해야 한다.

그러나 C++에서는 별도의 선언없이도 구조체 변수를 선언할 수 있다.


(2) 구조체 안에 함수 선언

C++에서는 구조체 안에 함수를 선언할 수 있다. 만약 그렇게 되면, 구조체의 멤버 변수를 별다른 연산 없이

참조할 수 있게 된다.

struct Stu
{
    int stu_num;
    char stu_name[10];

    void print_information( void)
    {
        cout<< stu_num << endl;
        cout<< stu_name << endl;
    }
};


(3) 구조체 안에 enum 상수 선언

특정 구조체에만 의미가 있는 상수들의 경우 열거형 enum을 통해 구조체 내에서만 유효한 상수를 정의하면 된다.

구조체 안에 enum을 사용하는 것이 부담스럽다면, 'namespace'를 통해 상수가 사용되는 영역을 명시하는 것도 방법이다.

namespace STU_CONST
{
    enum
    {
        NAME_LEN    = 10
    };

}
struct Stu
{
    int stu_num;
    char stu_name[STU_CONST::NAME_LEN];

    void print_information( void)
    {
        cout<< stu_num << endl;
        cout<< stu_name << endl;
    }
};


(4) 함수는 외부로 뺄 수 있다.

구조체 안에 함수의 구현 부분까지 포함시키면, 상대적으로 구조체를 한 눈에 파악하기가 힘들어졌다.

따라서 함수의 정의 부분만 구조체에 선언하고, 구현 부분은 밖으로 빼내는 것이다.

struct Stu
{
    int stu_num;
    char stu_name[10];

    void print_information( void);
};

void Stu::print_information( void)
{
    cout<< stu_num << endl;
    cout<< stu_name << endl;
}


※ 함수를 구조체 내부에 구현할 경우, "함수를 인라인으로 처리하라!"라는 의미가 내포되어 있다.

하지만 구조체 밖으로 빼내면 이러한 의미가 사라지므로 'inline'을 별도로 지정해 주어야 한다.

inline void Stu::print_information( void)
{
    cout<< stu_num << endl;
    cout<< stu_name << endl;
}


2. 클래스와 객체
앞서 설명한 C++의 구조체는 클래스의 일종이다. 그렇다면 클래스와 구조체에는 어떠한 차이점이 있을까?


(1) 클래스와 구조체의 차이점

키워드 'struct' 대신 'class'를 사용하면, 구조체가 아닌 클래스가 된다.

- 기본적으로 클래스 내에 선언된 변수는 클래스 내에 선언된 함수에서만 접근 가능.


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

C++의 접근제어 지시자는 다음과 같이 총 세가지가 존재한다.

- public : 어디서든 접근을 허용

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

- private : 클래스 내에서만 접근을 허용


함수의 정의를 클래스 밖으로 빼도, 이는 클래스의 일부이기 때문에 함수 내에서 'private'으로 선언된 변수에 접근이 가능


※ 구조체의 경우 기본적으로 'public'으로 선언이되고, 클래스의 경우 'private'로 선언이 된다.


(3) C++에서의 파일 분할

헤더(.h)파일 : 클래스의 선언(declaration)을 담는다.

CPP 파일 : 클래스의 정의(멤버함수의 정의)를 담는다.

클래스와 관련된 문장의 컴파일 정보로 사용되는 '클래스의 선언'은 헤더파일에 저장을 하여

필요한 위치에 쉽게 포함될 수 있도록 해야 하며, '클래스의 정의'는 소스 파일에 저장해서, 컴파일이 되도록 하면 된다.


(4) 인라인(inline) 함수는 헤더파일에 선언해야 한다.
클래스 선언을 헤더 파일에 두고, 인라인 함수를 .cpp 파일에 두면 컴파일 에러가 발생한다.

일반 함수라면, 멤버함수인지만 확인을 하고 컴파일이 완료가 되지만, 인라인의 경우 컴파일 시

함수의 호출문장은 함수의 몸체로 대체되어야 한다. 그러므로 선언과 동시에 파일에 저장되어 참조할 수 있게 해야 한다.


※ 컴파일은 파일 단위로 컴파일 하기 때문에, A.cpp와 B.cpp를 컴파일하여 하나의 실행 파일을 만든다 하여도,

A 컴파일 과정 중 B를 참조하지 않고, 반대로도 마찬가지다.


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

객체지향 프로그래밍은 현실에 존재하는 사물과 대상, 그리고 그에 따른 행동을

있는 그대로 실체화 시키는 형태의 프로그래밍이다.


(1) 객체를 이루는 것은 데이터와 기능이다.

'과일장수'를 기준으로 프로그램상에서 바라보는 관점은 '과일의 판매'이다.

즉, 다음과 같은 형태이다.

- 과일장수는 과일을 팝니다.

- 과일장수는 사과 20개, 오렌지 10개를 보유하고 있습니다.

- 과일장수의 과일판매 수익은 현재까지 50,000원입니다.

이 중 첫 번째는 '행동(behavior)'을 의미합니다. 그리고 두 번째와 세 번째는 과일장수의 '상태(state)'를 의미합니다.

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

상태 정보는 변수를 통해서 표현이 되고, 행동은 함수를 통해서 표현이 됩니다.


(2) 멤벼변수의 상수화에 대한 논의

- 클래스 멤버변수 선언문에서 초기화까지 하는 것을 허용하지 않는다.

- 상수는 선언과 동시에 초기화되어야 한다.

따라서 아래와 같은 두 가지 방법은 모두 불가능하다.

struct Stu
{
    const int value = 10; // (X)
};
struct Stu
{
    const int value; // 선언은 가능

    void init( void)
    {
        value = 10; // (X) 불가능
    }
};


이후에 생성자를 공부하면서 이에 대한 답을 찾을 것이다.


(3) 클래스 기반의 두 가지 객체를 생성하는 방법

- classname objname; // 일반적인 변수의 선언 방식

- classname *objname = new class name; // 힙 할당 방식

class Stu
{
    char stu_name[10];
    int stu_num;

    void print_information( void)
    {
        cout << stu_name << endl;
        cout << stu_num << endl;
    }
};

int main( void)
{
    Stu s1;
    Stu *s2 = new Stu;

}


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

하나의 객체가 다른 하나의 객체에게 메시지를 전달하는 방법은 함수 호출을 기반으로 한다.

그래서 객체지향에서는 이러한 형태의 함수호출을 가리켜 '메시지 전달(message passing)'이라 한다.

class Seller
{
    int costofitem; // private
    int numberofitem;
    int mymoney; // private

public:
    int sellingitem( int money)
    {
        int n   = money/costofitem;

        numberofitem    -= n;
        mymoney         += money;

        return n;
    }
};

class Buyer
{
    int numberofitem; // private
    int mymoney; // private

public:
    void buyingitem( Seller &s, int money)
    {
        numberofitem    += s.sellingitem(money);
        mymoney         -= money;
    }
};


출처 : 윤성우 열혈 C++ 프로그래밍