chapter 03. 클래스의 기본
1. 클래스로 나아갈 전단계, 구조체
1) C와 C++의 구조체 차이
struct Car{
~
};
struct Car FirstCar; // C의 구조체형 변수 선언 방식
Car SecondCar; // C++의 구조체형 변수 선언 방식
2) 구조체 종속성
> C++의 구조체는 클래스의 일종으로 간주되므로 구조체 안에 함수를 정의할 수 있다
> 이제는 '클래스' 라고 표현을 해도 되는 것
#include <iostream>
using namespace std;
#define ID_LEN 20
#define MAX_SPD 200
#define FUEL_STEP 2
#define ACC_STEP 10
#define BRK_STEP 10
// Car 구조체
struct Car {
char gamerID[ID_LEN]; // 게임 ID
int fuelGauge; // 연료 게이지
int curSpeed; // 현재 속도
};
// Car 상태 출력 함수 정의
void ShowCarState(const Car &car) {
cout << "게임 ID: " << car.gamerID << endl;
cout << "연료 게이지: " << car.fuelGauge << endl;
cout << "현재 속도: " << car.curSpeed << endl;
}
// main 함수
int main(void) {
Car myCar = {"Marin", 100, 0}; // Car 구조체 초기화
ShowCarState(myCar); // Car 상태 출력
return 0;
}
>
위 코드를 보면 구조체와 구조체 안의 변수들을 조작하는 함수가 분리되어 있음을 알 수 있다
따라서 이 함수들은 Car에 종속적인 함수들이라 할 수 없음
#include <iostream>
using namespace std;
#define ID_LEN 20
#define MAX_SPD 200
#define FUEL_STEP 2
#define ACC_STEP 10
#define BRK_STEP 10
// Car 구조체
struct Car {
char gamerID[ID_LEN]; // 게임 ID
int fuelGauge; // 연료 게이지
int curSpeed; // 현재 속도
// Car 상태 출력 함수 정의
void ShowCarState() {
cout << "게임 ID: " << gamerID << endl;
cout << "연료 게이지: " << fuelGauge << endl;
cout << "현재 속도: " << curSpeed << endl;
}
};
// main 함수
int main(void) {
Car myCar = {"Marin", 100, 0}; // Car 구조체 초기화
myCar.ShowCarState(); // Car 상태 출력
return 0;
}
>
위 처럼 구조체 안에 함수를 넣어 종속시키면 main에서는 구조체형 변수를 선언 후 구조체 안의 함수들을 꺼내서 사용할 수 있다
#include <iostream>
using namespace std;
#define ID_LEN 20
#define MAX_SPD 200
#define FUEL_STEP 2
#define ACC_STEP 10
#define BRK_STEP 10
// Car 구조체
struct Car {
char gamerID[ID_LEN]; // 게임 ID
int fuelGauge; // 연료 게이지
int curSpeed; // 현재 속도
// Car 상태 출력 함수 선언
void ShowCarState();
};
// Car 상태 출력 함수 정의
void Car::ShowCarState() {
cout << "게임 ID: " << gamerID << endl;
cout << "연료 게이지: " << fuelGauge << endl;
cout << "현재 속도: " << curSpeed << endl;
}
// main 함수
int main(void) {
Car myCar = {"Marin", 100, 0}; // Car 구조체 초기화
myCar.ShowCarState(); // Car 상태 출력
return 0;
}
> 구조체 안에 함수 선언 후 아래에 해당 함수가 어디 정의되었는지 정보를 주면 밖으로 빼서 함수를 정의할 수도 있다.
2. 클래스(Class) / 객체(Object)
1) 클래스와 구조체의 차이점
#include <iostream>
using namespace std;
#define ID_LEN 20
#define MAX_SPD 200
#define FUEL_STEP 2
#define ACC_STEP 10
#define BRK_STEP 10
// Car 클래스 정의
class Car {
private: // 접근제어 지시자(private)
char gamerID[ID_LEN]; // 게임 ID
int fuelGauge; // 연료 게이지
int curSpeed; // 현재 속도
// Car 상태 출력 함수 정의
public: // 접근제어 지시자(public)
void ShowCarState() {
cout << "게임 ID: " << gamerID << endl;
cout << "연료 게이지: " << fuelGauge << endl;
cout << "현재 속도: " << curSpeed << endl;
}
};
// main 함수
int main(void) {
Car myCar; // Car 클래스 초기화
myCar.ShowCarState(); // Car 상태 출력
return 0;
}
첫번째로 키워드를 struct에서 class로 변경했다는 점
두번째로 접근제어 지시자를 명시했다는 점
: class의 경우 접근제어 지시자를 생략하면 private가 기본적으로 할당되고,
struct의 경우 접근제어 지시자를 생략하면 public이 기본적으로 할당된다는 차이점이 있다.
세번째로 클래스를 초기화 방식이 다르다는 점
: struct는 Car myCar = {~}; 형식으로 초기화하는 반면 class는 클래스 변수 선언이 전부이다
2) 용어정리
- 객체 : 위에서 Car myCar; 부분 생성된 myCar 변수를 의미함
- 멤버변수 : 클래스 내의 선언된 변수들
- 멤버함수 : 클래스 내의 정의된 함수들
chapter 04. 클래스의 완성
1. 정보은닉(InformationHiding)
1) 문제의 발단
> public의 문제
#include<iostream>
using namespace std;
class Point
{
public:
int x; // x좌표의 범위는 0이상 100이하.
int y; // y좌표의 범위는 0이상 100이하.
};
class Rectangle
{
public:
Point upLeft;
Point lowRight;
public:
void ShowRecInfo()
{
cout<<"좌 상단: "<<'['<<upLeft.x<<", ";
cout<<upLeft.y<<']'<<endl;
cout<<"우 하단: "<<'['<<lowRight.x<<", ";
cout<<lowRight.y<<']'<<endl<<endl;
}
};
int main(void)
{
Point pos1={-2, 4};
Point pos2={5, 9};
Rectangle rec={pos2, pos1};
rec.ShowRecInfo();
return 0;
}
Point 클래스 멤버변수가 public으로 선언되었을 때 문제점
Point 클래스의 멤버변수의 의도는 x, y 둘 다 0 이상 100 이하의 숫자가 들어가는 것인데
실제 main에서 보면 Point 클래스를 음수로 초기화하는 모습을 볼 수 있음
변수를 변경하는 행위를 제한할 수 없는 것이 큰 문제이다
2) 문제의 해결
>제한된 방법으로의 접근만 허용을 하여 잘못된 값이 저장되지 않도록 돕는 것
#include <iostream>
using namespace std;
// Point 클래스 정의
class Point
{
private: // 접근 제어 지시자(private) -> 정보은닉
int x;
int y;
public: // 접근 제어 지시자(public)
bool InitMembers(int xpos, int ypos);
int GetX() const;
int GetY() const;
bool SetX(int xpos);
bool SetY(int ypos);
};
// Point 클래스 멤버 초기화 함수
// 값이 잘못 전달될 경우 에러 메시지를 출력하여 클래스 내 은닉변수들을 안전하게 보호함
bool Point::InitMembers(int xpos, int ypos)
{
if(xpos < 0 || ypos < 0)
{
cout << "벗어난 범위의 값 전달" << endl;
return false;
}
x = xpos;
y = ypos;
return true;
}
// Point 클래스 엑세스 함수
// 호출되지 않는 경우가 많음
int Point::GetX() const { return x; }
int Point::GetY() const { return y; }
bool Point::SetX(int xpos)
{
if(xpos < 0 || xpos > 100)
{
cout << "벗어난 범위의 값 전달" << endl;
return false;
}
x = xpos;
return true;
}
bool Point::SetY(int ypos)
{
if(ypos < 0 || ypos > 100)
{
cout << "벗어난 범위의 값 전달" << endl;
return false;
}
y = ypos;
return true;
}
// Rectangle 클래스 정의
class Rectangle
{
private:
Point upLeft; // 좌상단 좌표
Point lowRight; // 우하단 좌표
public:
bool InitMembers(const Point& p1, const Point& p2);
void ShowRecInfo() const;
};
// Rectangle 클래스 멤버 초기화 함수
// 두 좌표가 잘못된 경우 에러 메시지를 출력하여 클래스 내 은닉
bool Rectangle::InitMembers(const Point& p1, const Point& p2)
{
if(p1.GetX() > p2.GetX() || p1.GetY() > p2.GetY())
{
cout << "좌표가 잘못되었습니다." << endl;
return false;
}
upLeft = p1;
lowRight = p2;
return true;
}
// Rectangle 클래스 정보 출력 함수
void Rectangle::ShowRecInfo() const
{
cout << "좌상단: (" << upLeft.GetX() << ", " << upLeft.GetY() << ")" << endl;
cout << "우하단: (" << lowRight.GetX() << ", " << lowRight.GetY() << ")" << endl;
}
int main(void){
Point p1;
if(!p1.InitMembers(-2, 5))
cout << "좌표 초기화 실패" << endl;
if(!p1.InitMembers(2, 5))
cout << "좌표 초기화 실패" << endl;
Point p2;
if(!p2.InitMembers(5, 10))
cout << "좌표 초기화 실패" << endl;
Rectangle rec;
if(!rec.InitMembers(p1, p2))
cout << "사각형 초기화 실패" << endl;
if(!rec.InitMembers(p2, p1))
cout << "사각형 초기화 실패" << endl;
rec.ShowRecInfo();
return 0;
}
>
첫번째로 Point 클래스를 선언하고, 멤버변수를 private로 선언, 해당 변수에 접근하는 함수들은 public으로 정의함
두번째로 Rectangle 클래스를 선언하고, 멤버변수를 private로 선언, 해당 변수에 접근하는 함수들은 public으로 정의함
세번째로 main을 보면
p1 객체를 선언 후 p1 객체 안의 멤버변수에 접근할 수 있는 함수를 사용해서 멤버변수를 초기화 시도를 하고 있음
p2 객체를 선언 후 위와같이 시도함
rec 객체를 선언 후 rec 객체 안의 InitMembers 함수를 사용하는데, 이 함수는 인자로 받은 p1과 p2 안의 공개적으로 접근 가능한 GetX(), GetY() 함수를 이용하여 멤버변수를 초기화 시도함
3) const 함수
> class 내 public인 함수를 통해 누구든 멤버변수의 값을 변경할 수 있는데, 그 값을 변경할 수 없고 기능만 사용할 수 있도록 만들어놓은 함수
int GetX() const;
int GetY() const;
void ShowRecInfo() const;
>
여기서 사용된 const는 이 함수 내에서는 멤버변수의 값을 변경할 수 없도록 함
point 클래스의 public 인 GetX()와 GetY()가 Rectangle 클래스의 ShowRecInfo()에서 사용되었는데, const를 지정함으로써 멤버변수의 값에 변경을 가할 수 없도록 만들어 놓은 것임
2. 캡슐화(Encapsulation)
1) 캡슐화란?
> 하나의 목적을 위해 둘 이상의 기능이 모은 것
> 하나의 목적이라고 여긴 것들이 확장된다면, 이를 위한 기능들은 캡슐화를 제대로 수행하지 못하는 것이 되고 결국 기능들 또한 확장될 필요가 있다
#include <iostream>
using namespace std;
class SinivelCap // 콧물 처치용 캡슐
{
public:
void Take() const {cout<<"콧물이 싹~ 납니다."<<endl;}
};
class SneezeCap // 재채기 처치용 캡슐
{
public:
void Take() const {cout<<"재채기가 멎습니다."<<endl;}
};
class SnuffleCap // 코막힘 처치용 캡슐
{
public:
void Take() const {cout<<"코가 뻥 뚫립니다."<<endl;}
};
class ColdPatient
{
public:
void TakeSinivelCap(const SinivelCap &cap) const {cap.Take();}
void TakeSneezeCap(const SneezeCap &cap) const {cap.Take();}
void TakeSnuffleCap(const SnuffleCap &cap) const{cap.Take();}
};
int main(void)
{
SinivelCap scap;
SneezeCap zcap;
SnuffleCap ncap;
ColdPatient sufferer;
sufferer.TakeSinivelCap(scap);
sufferer.TakeSneezeCap(zcap);
sufferer.TakeSnuffleCap(ncap);
return 0;
}
>
위를 보면 캡슐화가 잘되어 있다고 생각을 했는데
실제 코감기가 콧물, 재채기, 코막힘의 증상을 모두 발생시키고 이를 한번에 치료해야 할 필요성이 있다면
코감기라는 증상을 치료하는데에 목적이 있기에 캡슐화는 제대로 되지 않은 것
또한 복용 순서가 무조건 정해져 있는 상황(sin -> snz -> snu 순)인데
환자 클래스가 복용을 snz -> snu -> sin(예) 순으로 하면 부작용이라는 결과를 낳게 되고
이 또한 치료의 목적이 있기에 캡슐화는 제대로 되지 않은 것
#include <iostream>
using namespace std;
class SinivelCap // 콧물 처치용 캡슐
{
public:
void Take() const {cout<<"콧물이 싹~ 납니다."<<endl;}
};
class SneezeCap // 재채기 처치용 캡슐
{
public:
void Take() const {cout<<"재채기가 멎습니다."<<endl;}
};
class SnuffleCap // 코막힘 처치용 캡슐
{
public:
void Take() const {cout<<"코가 뻥 뚫립니다."<<endl;}
};
class CONTAC600
{
private:
SinivelCap sin;
SneezeCap sne;
SnuffleCap snu;
public:
void Take() const
{
sin.Take();
sne.Take();
snu.Take();
}
};
class ColdPatient
{
public:
void TakeCONTAC600(const CONTAC600 &cap) const { cap.Take(); }
};
int main(void)
{
CONTAC600 cap;
ColdPatient sufferer;
sufferer.TakeCONTAC600(cap);
return 0;
}
>
따라서 목감기 치료라는 목적을 위해서는
ColdPatient 클래스형 변수 sufferer은 복용 행위만 하고
contac600 이라는 클래스의 take() 에서 순서를 직접 조절하고 모두 복용하도록 해야한다
3. 생성자(Constructor) / 소멸자(Destructor)
1) 생성자
> 객체의 멤버변수 초기화를 위한 함수
class single
{
~
public:
single(); // 생성자
};
>
- 클래스명을 함수 이름으로 사용함
- 반환형이 없음
#include <iostream>
using namespace std;
// SimpleClass 클래스 정의
class SimpleClass
{
int num1;
int num2;
// 생성자 오버로딩
public:
SimpleClass() // 기본 생성자
{
num1=0;
num2=0;
}
SimpleClass(int n) // 매개변수 1개인 생성자
{
num1=n;
num2=0;
}
SimpleClass(int n1, int n2) // 매개변수 2개인 생성자
{
num1=n1;
num2=n2;
}
/* 주석을 해제하면 22행과 인자가 같아 오버로딩이 불가능
SimpleClass(int n1=0, int n2=0)
{
num1=n1;
num2=n2;
}
*/
void ShowData() const
{
cout<<num1<<' '<<num2<<endl;
}
};
int main(void)
{
SimpleClass sc1;
sc1.ShowData();
SimpleClass sc2(100);
sc2.ShowData();
SimpleClass sc3(100, 200);
sc3.ShowData();
return 0;
}
>
- 오버로딩이 가능함
- 디폴트 값을 설정할 수 있다
2) 소멸자
#include <iostream>
#include <cstring>
using namespace std;
class Person
{
private:
char * name;
int age;
public:
Person(char * myname, int myage)
{
int len=strlen(myname)+1;
name=new char[len]; // 동적 메모리 할당
strcpy(name, myname);
age=myage;
}
void ShowPersonInfo() const
{
cout<<"이름: "<<name<<endl;
cout<<"나이: "<<age<<endl;
}
~Person() // 소멸자
{
delete []name; // 동적 메모리 해제
cout<<"called destructor!"<<endl;
}
};
int main(void)
{
Person man1("Lee dong woo", 29);
Person man2("Jang dong gun", 41);
man1.ShowPersonInfo();
man2.ShowPersonInfo();
return 0;
}
>
- '~' 가 앞에 붙은 형태
- 반환형이 없음
- 오버로딩 불가능
- 디폴트 값 설정 불가능
4. this 포인터
> 클래스명 자신을 가리키는 포인터
#include <iostream>
#include <cstring>
using namespace std;
class SoSimple
{
int num;
public:
SoSimple(int n) : num(n) // 생성자로 멤버변수 초기화
{
cout<<"num="<<num<<", "; // 멤버변수 출력
cout<<"address="<<this<<endl; // this 포인터 출력
}
void ShowSimpleData() // 멤버변수 출력
{
cout<<num<<endl;
}
SoSimple * GetThisPointer() // SoSimple 클래스형 this 포인터 반환
{
return this;
}
};
int main(void)
{
SoSimple sim1(100);
SoSimple * ptr1=sim1.GetThisPointer();
cout<<ptr1<<", ";
ptr1->ShowSimpleData();
SoSimple sim2(200);
SoSimple * ptr2=sim2.GetThisPointer();
cout<<ptr2<<", ";
ptr2->ShowSimpleData();
return 0;
}
study
1. 177p~
#ifndef __POINT_H_
#define __POINT_H_
class Point
{
int x;
int y;
public:
Point(const int &xpos, const int &ypos);
int GetX() const;
int GetY() const;
bool SetX(int xpos);
bool SetY(int ypos);
};
#endif
<Point.h>
#ifndef __POINT_H_ / #define __POINT_H_ / #endif
: 헤더 파일 중복 포함을 방지함. 같은 헤더 파일이 여러 번 포함돼도 컴파일 오류가 발생하지 않도록 코드가 한 번만 처리되게 하는 중요한 역할임.
int x; 와 int y;
: 점의 x, y 좌표를 저장함. 클래스 밖에서는 직접 접근할 수 없는 private 멤버로 선언되어 데이터를 보호하고, 클래스 내부의 메서드를 통해서만 조작할 수 있음.
Point(const int &xpos, const int &ypos);
: 객체가 생성될 때 호출되어 x와 y 좌표를 초기화함. const int &는 데이터를 복사하지 않고 원본을 참조하여 효율적이며, const를 통해 값을 변경하지 않겠다는 것을 명시함.
int GetX() const; / int GetY() const;
: 이 메서드들은 점의 좌표를 반환함. 메서드 끝에 붙은 const는 이 함수가 클래스의 멤버 변수 값을 변경하지 않는다는 것을 보장함.
bool SetX(int xpos); 와 bool SetY(int ypos);
: 이 메서드들은 점의 좌표를 설정함. 반환 타입이 bool인 이유는 좌표값이 유효한지 확인하고, 유효하지 않은 경우 false를 반환하는 등의 예외 처리를 나중에 추가할 수 있도록 유연성을 주기 위함임.
#include <iostream>
#include "Point.h" // class를 참조하기 위한 include
using namespace std;
Point::Point(const int &xpos, const int &ypos)
{
x=xpos;
y=ypos;
}
int Point::GetX() const {return x;}
int Point::GetY() const {return y;}
bool Point::SetX(int xpos)
{
if(0>xpos || xpos>100)
{
cout<<"벗어난 범위의 값 전달"<<endl;
return false;
}
x=xpos;
return true;
}
bool Point::SetY(int ypos)
{
if(0>ypos || ypos>100)
{
cout<<"벗어난 범위의 값 전달"<<endl;
return false;
}
y=ypos;
return true;
}
<Point.cpp>
#include "Point.h"
: Point 클래스의 정의가 담긴 헤더 파일을 포함하여, Point 클래스에 속한 메서드를 구현할 수 있도록 함.
Point::Point(const int &xpos, const int &ypos)
: Point 객체가 생성될 때 호출되는 생성자임. 매개변수로 받은 xpos와 ypos의 값을 클래스의 멤버 변수인 x와 y에 각각 대입하여 객체를 초기화하는 역할을 함.
int Point::GetX() const {return x;}
: x 좌표의 값을 반환함. const로 선언되어 있어 객체의 상태(멤버 변수)를 변경하지 않고 단순히 읽는 역할만 하는 것을 보장함.
int Point::GetY() const {return y;}
: y 좌표의 값을 반환함. 위와 같음.
bool Point::SetX(int xpos)
: x 좌표의 값을 설정함. 이 메서드는 매개변수 xpos가 0에서 100 사이의 유효한 값인지 먼저 검사,
만약 값이 범위를 벗어났을 경우, 오류 메시지를 출력하고 false를 반환하여 값 설정에 실패했음을 알림.
값이 유효하면 멤버 변수 x에 xpos를 대입하고 true를 반환하여 성공적으로 값을 설정했음을 알림.
bool Point::SetY(int ypos)
: y 좌표의 값을 설정함. 위와 같음
#ifndef __RECTANGLE_H_
#define __RECTANGLE_H_
#include "Point.h"
class Rectangle
{
Point upLeft;
Point lowRight;
public:
Rectangle(const int &x1, const int &y1, const int &x2, const int &y2);
void ShowRecInfo() const;
};
#endif
<Rectangle.h>
#ifndef __RECTANGLE_H_ / #define __RECTANGLE_H_
: 헤더 파일의 중복 포함을 방지함.
#include "Point.h"
: Rectangle 클래스 내부에서 Point 클래스의 객체를 사용하기 위해 Point.h 헤더 파일을 포함.
Point upLeft; / Point lowRight;
: 클래스 밖에서는 직접 접근할 수 없는 private 멤버로 선언되어 데이터를 보호하고, 클래스 내부의 메서드를 통해서만 조작할 수 있음.
Rectangle(const int &x1, const int &y1, const int &x2, const int &y2);
: 생성자. 사각형을 초기화하기 위해 왼쪽 위 꼭짓점의 좌표(x1, y1)와 오른쪽 아래 꼭짓점의 좌표(x2, y2)를 받음.
void ShowRecInfo() const;
: 사각형의 정보를 출력하는 메서드임. const가 붙어 있어 이 메서드가 객체의 상태(멤버 변수)를 변경하지 않고 정보를 보여주기만 하는 역할임.
#include <iostream>
#include "Rectangle.h"
using namespace std;
Rectangle::Rectangle(const int &x1, const int &y1, const int &x2, const int &y2)
:upLeft(x1, y1), lowRight(x2, y2)
{
// empty
}
void Rectangle::ShowRecInfo() const
{
cout<<"좌 상단: "<<'['<<upLeft.GetX()<<", ";
cout<<upLeft.GetY()<<']'<<endl;
cout<<"우 하단: "<<'['<<lowRight.GetX()<<", ";
cout<<lowRight.GetY()<<']'<<endl<<endl;
}
<Rectangle.cpp>
#include "Rectangle.h"
: Rectangle 클래스의 정의가 담긴 헤더 파일을 포함하여 해당 클래스의 메서드를 구현할 수 있게 했음.
Rectangle::Rectangle(const int &x1, const int &y1, const int &x2, const int &y2)
: Rectangle 객체를 만들 때 호출됨.
upLeft(x1, y1), lowRight(x2, y2)
: 초기화 리스트. 생성자의 몸체 {} 안에서 값을 대입하는 대신, 멤버 변수인 upLeft와 lowRight를 생성과 동시에 x1, y1과 x2, y2로 초기화했음. 이 방식은 생성자 몸체에서 대입하는 것보다 더 효율적.
void Rectangle::ShowRecInfo() const
: 사각형의 좌측 상단과 우측 하단 좌표를 출력하는 역할을 함.
upLeft.GetX() / upLeft.GetY() / lowRight.GetX() / lowRight.GetY()
: 각각 upLeft와 lowRight 라는 Point 객체의 GetX()와 GetY() 메서드를 호출하여 좌표를 가져옴.
ShowRecInfo const
: 이 메서드가 객체의 데이터를 변경하지 않고 단순히 정보를 출력하는 기능만 수행한다는 것을 보장함.
#include<iostream>
#include "Point.h"
#include "Rectangle.h"
using namespace std;
int main(void)
{
Rectangle rec(1, 1, 5, 5);
rec.ShowRecInfo();
return 0;
}
<RectangleConstructor.cpp>
Rectangle rec(1, 1, 5, 5);
: Rectangle 클래스의 객체 rec를 생성함. 생성자에 전달된 (1, 1)은 사각형의 좌측 상단 꼭짓점 좌표를, (5, 5)는 우측 하단 꼭짓점 좌표를 의미함.
rec.ShowRecInfo();
: rec 객체의 ShowRecInfo() 메서드를 호출함. 이 메서드는 객체가 가지고 있는 좌표 정보를 콘솔에 출력함.
2. 181p~
#include <iostream>
using namespace std;
class FruitSeller
{
const int APPLE_PRICE;
int numOfApples;
int myMoney;
public:
FruitSeller(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() const
{
cout<<"남은 사과: "<<numOfApples<<endl;
cout<<"판매 수익: "<<myMoney<<endl<<endl;
}
};
class FruitBuyer
{
int myMoney;
int numOfApples;
public:
FruitBuyer(int money)
: myMoney(money), numOfApples(0)
{
}
void BuyApples(FruitSeller &seller, int money)
{
numOfApples+=seller.SaleApples(money);
myMoney-=money;
}
void ShowBuyResult() const
{
cout<<"현재 잔액: "<<myMoney<<endl;
cout<<"사과 개수: "<<numOfApples<<endl<<endl;
}
};
int main(void)
{
FruitSeller seller(1000, 20, 0);
FruitBuyer buyer(5000);
buyer.BuyApples(seller, 2000);
cout<<"과일 판매자의 현황"<<endl;
seller.ShowSalesResult();
cout<<"과일 구매자의 현황"<<endl;
buyer.ShowBuyResult();
return 0;
}
- FruitSeller 클래스
const int APPLE_PRICE
: 사과의 가격을 나타내며, const로 선언되어 객체 생성 후 가격이 변하지 않도록 함.
int numOfApples
: 판매자가 가지고 있는 사과의 개수.
int myMoney
: 판매자의 판매 수익임.
FruitSeller(int price, int num, int money) / APPLE_PRICE(price), numOfApples(num), myMoney(money)
: 생성자. 초기화 리스트를 사용해 사과 가격, 개수, 수익을 초기화함.
- FruitBuyer 클래스
int myMoney
: 구매자의 현재 잔액.
int numOfApples
: 구매자가 가진 사과의 개수.
FruitBuyer(int money)
myMoney(money), numOfApples(0)
: 생성자. 초기화 리스트를 사용해 구매자의 돈과 사과 개수를 초기화함.
5. 203p~
'LMS 7 > 개발일지' 카테고리의 다른 글
| 25.07.25 개발일지 / 빌드 및 Make (3) | 2025.07.29 |
|---|---|
| 25.07.24 학습개발일지 / C++ (5) | 2025.07.29 |
| 25.07.22 학습일지 / C++ (3) | 2025.07.29 |
| 25.07.21 개발일지 / 채팅 프로그램 5팀 (1) | 2025.07.29 |
| 25.07.18 개발일지 / 채팅 프로그램 5팀 (3) | 2025.07.29 |