본문 바로가기
코스웨어/16년 스마트컨트롤러

2016-09-23_조재찬_스터디일지_CPP-OOP (객체지향 프로그래밍)

by 알 수 없는 사용자 2016. 9. 23.
728x90
반응형

Object Oriented Programming (객체지향 프로그래밍)


C++은 객체지향 언어

C언어가 절차지향적 언어라면 C++은 객체지향 언어


"나는 과일장수에게 두 개의 사과를 구매했다!"

위 문장에서 object(객체)는 나, 과일장수, 사과



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

프로그램상에서 바라보는 과일장수

- 과일장수는 과일을 판다                            (행동 behavior)

- 과일장수는 사과 20개, 오렌지 10개를 보유    (상태 state)

- 과일장수의 판매 수익은 현재 50,00원           (상태 state)


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


상태 정보 : 변수를 통해서 표현(변수에 상태 정보 저장)

행동 : 함수를 통해서 표현



과일 장수의 상태 정보 (변수로 표현하며, 사과를 판다고 가정)

 - 보유 사과 수    -> int numOfApples;

 - 판매 수익        -> int myMoney;


과일 장수의 행위 (판매를 함수로 표현)


1
2
3
4
5
6
7
int SaleApples(int money)      // 함수의 인자는 사과 구매 금액
{
    int num = money / 1000;    // 사과는 개당 1000원
    numOfApples -= num;        //  사과수 감소  
    myMoney += money;          // 판매 수익 발생
    return num;                // 판매된 사과의 수를 반환
}
cs



class는 객체를 생성하기 위한 틀

변수 초기화 함수와 과일장수의 판매수익, 남는 사과 개수를 보여주는 함수도 정의

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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<<endl;
    }
};
cs

위에서 사과의 판매 가격을 의미하는 멤버변수 APPLE_PRICE를 상수화 하고 싶지만 다음과 같은 이유로 '현재 공부한 내용에서는 불가능'하다.

 클래스의 멤버변수 선언문에서 초기화까지 하는 것은 허용하지 않는다. const int APPLE_PRICE=1000;    (x)
 상수는 선언과 동시에 초기화 해야한다. const int APPLE_PRICE;    (x)

이 문제는 후에 생성자(Constructor)를 공부하게 되면 해결할 수 있게 된다.



구매자인 나(me)를 표현하는 클래스 정의
과일 구매자를 뜻하는 FruitBuyer 클래스

멤버 변수
 소유한 현금 -> int myMoney;
 소유한 사과 -> int numOfApples;


과일구매자의 기능
: 과일의 구매 (함수 BuyApple)

이를 기반으로 정의한 FruitBuyer 클래스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
    }
};
cs

3,4행에서 클래스에 아무런 선언이 존재하지 않을 때 private로 간주 (구조체는 public)


클래스 기반의 두 가지 객체 생성 방법  (클래스의 실체화 : 객체화)
앞서말했듯이 클래스는 객체를 생성하기 위한 틀에 불가하다.

그러니 객체를 생성하지 않고 두 클래스 안에 존재하는 변수에 접근하고, 함수를 호출하는 것은 불가능하다. 

C++에서 객체를 생성하는 두 가지 방법은 다음과 같다.

ClassName objName;                // 일반적 변수 선언방식
ClassName * ptrobj = new ClassName; // 동적 할당방식 (heap 할당)


일반적 변수 선언방식으로 FruitSeller 클래스와 FruitBuyer 클래스 객체 생성
 FruitSeller seller;
 FruitBuyer buyer;

이를 동적 할당 (heap 할당)
 FruitSeller * objPtr1 = new FruitSeller;
 FruitBuyer * objPtr2 = new FruitBuyer;



Message Passing (객체간의 메시지 전달)

 "과일장수(seller) 아저씨, 사과 2000원어치 주세요"
-> '나'라는 객체가 '과일장수'라는 객체로부터 '과일'객체를 구매하는 행위의 표현
(이 행위의 결과는 아래 예제에서 보듯이 사과의 갯수가 증가하고 보유 현금이 줄어드는 것이 됨)

이는 하나의 객체가 다른 하나의 객체에게 메시지를 전달하는 것과 같다.
과일장수(seller) 아저씨, 사과 2000원어치 주세요
이처럼 하나의 객체가 다른 하나의 객체에게 메시지를 전달하는 것은 함수 호출을 기반으로 하며,
이러한 형태의 함수호출을 'Message Passing (객체간의 메시지 전달)' 이라고 한다.

사과 장수 시뮬레이션 예제
#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 << 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;
}


Output:
1
2
3
4
5
6
7
8
과일 판매자의 현황
남은 사과: 18
판매 수익: 2000

과일 구매자의 현황
현재 잔액: 3000
사과 개수: 2


728x90