공부/C++

[C++] 3-3. 객체 지향 프로그래밍의 이해

knhoo 2024. 9. 21. 17:22
728x90

*윤성우의 열혈 C++ 프로그래밍 교재로 학습하며 정리하였습니다.

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

객체 지향 프로그래밍은 현실에 존재하는 사물과 대상,

그리고 그에 따른 행동을 있는 그대로 실체화 시키는 형태의 프로그래밍이다.

 

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

상태 정보(데이터)는 변수를 통해 표현되며

행동(기능)은 함수를 통해서 표현이 된다.

 

예를들어 아래와 같은 문장에서

"나는 과일장수에게 2,000원을 주고 두 개의 사과를 구매했다."

객체는 ,과일장수,사과라고 볼 수 있다.

(두 개 : 데이터, 구매했다 : 행위)

 

'과일장수'객체의 관점에서 다음과 같이 이루어져있다고 볼 수 있다.

 

상태 정보(데이터) :
보유하고있는 사과의 수 : 20개
판매 수익 : 50,000원

행동(기능) :
과일을 판다.


 

객체 생성을 위한 틀, 멤버변수의 상수화

객체를 생성하기에 앞서 객체의 생성을 위한 '틀(mold)'를 먼저 만들어야 한다.

붕어빵을 만들기 위해서 붕어빵 틀이 필요한 것과 유사하다.

마찬가지로 '나'와 '과일장수' 객체를 생성하기 위해서는 먼저 틀을 만들어야 한다.

class FruitSeller {
private:
    //상태 정보(데이터)
    int APPLE_PRICE; //사과의 가격
    int numOfApples; //보유하고 있는 사과의 수
    int myMoney; //판매 수익

public:
    void InitMembers(int price, int num, int money) {
        APPLE_PRICE = price;
        numOfApples = num;
        myMoney = money;
    }

    int SaleApples(int money) { //행위 : 과일 판매
        int num = money / APPLE_PRICE;
        numOfApples -= num;
        myMoney += money;
        return num; //판매한 과일의 수를 반환
    }

    void ShowSalesResult() {
        cout << "남은 사과: " << numOfApples << endl;
        cout << "판매 수익: " << myMoney << endl;
    }
};

 

위와 같이 FruitSeller라는 이름의 클래스가 과일장수의이 되는 것이다.


한편 변수 APPLE_PRICE를 const 선언을 통해 상수화 할 수 있을까? 

const int  APPLE_PRICE = 1000;

라고 하면 될 것같지만, 클래스의 멤버변수 선언문에서 초기화까지 하는 것을

허용하지 않기 때문에  불가능하다.

 

그렇다면, 아래와 같은 문장은 가능할까?

const int  APPLE_PRICE;

상수는 선언과 동시에 초기화되어야하기 때문에 이 방법도 불가능하다.


'나'의 객체의 틀이 되는 클래스도 다음과 같이 만들 수 있다.

class FruitBuyer {
    int myMoney; //접근제어 지시자 생략 시 private:
    int numofApples; //private:
public :
    void InitMembers(int money) {
        myMoney = money;
        numofApples = 0;
    }
    void BuyApples(FruitSeller& seller, int money) {
        numofApples += seller.SaleApples(money);
        myMoney -= money;
    }
    void ShowBuyResult() {
        cout << "현재 잔액: " << myMoney << endl;
        cout << "사과 개수: " << numofApples << endl;
    }
};

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

위에서 정의한 두 클래스 안에 존재하는 변수에 접근하고,함수를 호출하기 위해서는

객체 생성이 필요하다.

클래스는 실체(객체)가 아닌 틀이기 때문에 객체 생성 없이 접근 및 호출불가능하다.

붕어빵의 틀만으로 먹을 수 없다는 사실과 비슷하다.

 

C++에서 정의하고 있는 두 가지 객체 생성 방법을 살펴보자.

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

 


전체 코드를 완성해보면 다음과 같다.

#include <iostream>
using namespace std;

class FruitSeller {
private:
    //상태 정보(데이터)
    int APPLE_PRICE; //사과의 가격
    int numOfApples; //보유하고 있는 사과의 수
    int myMoney; //판매 수익

public:
    void InitMembers(int price, int num, int money) {
        APPLE_PRICE = price;
        numOfApples = num;
        myMoney = money;
    }

    int SaleApples(int money) { //행위 : 과일 판매
        int num = money / APPLE_PRICE;
        numOfApples -= num;
        myMoney += money;
        return num; //판매한 과일의 수를 반환
    }

    void ShowSalesResult() {
        cout << "남은 사과: " << numOfApples << endl;
        cout << "판매 수익: " << myMoney << endl;
    }
};

class FruitBuyer {
    int myMoney;  //접근제어 지시자 생략 시 private:
    int numofApples; //private:

public :
    void InitMembers(int money) {
        myMoney = money;
        numofApples = 0;
    }
    void BuyApples(FruitSeller& seller, int money) {
        numofApples += seller.SaleApples(money);
        myMoney -= money;
    }
    void ShowBuyResult() {
        cout << "현재 잔액: " << myMoney << endl;
        cout << "사과 개수: " << numofApples << endl << endl;
    }
};

int main(void) {
    FruitSeller seller;//객체 생성
    seller.InitMembers(1000, 20, 0);
    FruitBuyer buyer;//객체 생성
    buyer.InitMembers(5000);
    buyer.BuyApples(seller, 2000); //과일 구매

    cout << "과일 판매자의 현황" << endl;
    seller.ShowSalesResult();
    cout << "과일 구매자의 현황" << endl;
    buyer.ShowBuyResult();
    return 0;
}


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

numofApples += seller.SaleApples(money);

이 부분에서 FruitBuyer객체에 존재하는 함수 내에서 FruitSeller 객체의 함수 SaleApples를 호출하고 있다.

'나'라는 객체가 '과일장수'라는 객체로부터 '과일'객체를 구매하는 행위도 그대로 표현할 수 있는 것이다.

 

buyer.BuyApples(seller, 2000);

이는 FruitBuyer 객체가 FruitSeller 객체에게 

"seller아저씨, 사과 2000원어치 주세요.."라고 말하는 것과 같다.

 

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

객체 지향에서는 이러한 형태의 함수 호출을 가리켜

'메시지 전달(Message Passing)'이라 한다.

 

buyer.BuyApples(seller, 2000); 를 통해 메세지 전달이 시작되고,

numofApples += seller.SaleApples(money); 에서 메세지가 전달된다고 볼 수 있다.


정리

C++에서 클래스를 설계하는 것이 프로그래밍이라고 볼 수 있다.

클래스를 설계하는것은 객체를 설계하는 것과 같다.

객체 지향 프로그래밍은 현실 세계에 있는 객체들을 그대로 표현하는 것이다.

 

 

728x90