클래스와 클래스 메서드 정의
//stock00.h
//version 00
#ifndef STOCCK00_H_ //전처리 지시자 #define에 정의되어 있지 않은 경우에만,
#define STOCK00_H_ // #ifndef와 #endif 사이에 있는 구문을 처리
#include<string>
class Stock
{
private:
std::string company;
long shares;
double share_val;
double total_val;
void set_tot() { total_val = shares * share_val; }
public:
void acquire(const std::string& co, long n, double pr);
void buy(long num, double price);
void sell(long num, double price);
void update(double price);
void show();
}; //class 끝에 ;
#endif
//stock00.cpp
//version 00
#include <iostream>
#include "stock00.h"
void Stock::acquire(const std::string& co, long n, double pr) //해당 회사 주식 첫 취득
// 멤버함수를 정의할 때, 그 멤버 함수가 어느 클래스에 속하는지 나타내는 사용 범위 결정 연산자
{
company = co;
if (n < 0)
{
std::cout << "주식 수는 음수가 될 수 없으므로,"
<< company << " shares를 0으로 설정합니다. \n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
void Stock::buy(long num, double price) //기존 보유 주식의 증가와 감소 관리
{
if (num < 0)
{
std::cout << "매입 주식 수는 음수가 될 수 없으므로, "
<< "거래가 취소되었습니다.\n";
}
else
{
shares += num;
share_val = price;
set_tot();
}
}
void Stock::sell(long num, double price) //기존 보유 주식의 감소 관리
{
using std::cout;
if (num < 0)
{
cout << "모두 주식 수는 음수가 될 수 없으므로, "
<< "거래가 취소되었습니다. \n";
}
else if (num >shares)
{
cout << "보유 주식보다 많은 주식을 매도할 수 없으므로, "
<< "거래가 취소되었습니다. \n";
}
else
{
shares -= num;
share_val = price;
set_tot();
}
}
void Stock::update(double price)
{
share_val = price;
set_tot();
}
void Stock::show()
{
std::cout << "회사명: " << company
<< " 주식 수: " << shares << '\n'
<< " 주가: $" << share_val
<< " 주식 총 가치: $" << total_val << '\n';
}
acquire() : 해당 회사 주식의 첫 취득을 관리
buy(), sell() : 기존 보유 주식의 증가와 감소 관리
매입 주식 수 또는 매도 주식 수가 음수가 될 수 없게 관리
보유하고 있는 주식보다 많은 주식을 매도하려고 시도하는 경우 sell()함수에서 거래 취소
total_val 멤버의 값 : 네 개의 멤버 함수가 설정 / 재설정
-> 각 함수로 하여금 set_tot() 함수 호출로 멤버의 값을 설정하는 계산을 각각 작성을 방지
-> set_tot()는 private 멤버함수 [클래스 자체를 작성한 사람이 사용하는 멤버함수]
-> 계산을 수정할 경우에 set_tot() 함수만 수정 가능
클래스 객체 생성하고 사용하는 프로그램 작성
//usestock0.cpp -- 고객 프로그램
//stock00.cpp와 컴파일
#include <iostream>
#include "stock00.h"
int main()
{
Stock fluffy_the_cat;
fluffy_the_cat.acquire("NanoSmart", 20, 12.50);
fluffy_the_cat.show();
fluffy_the_cat.buy(15, 18.125);
fluffy_the_cat.show();
fluffy_the_cat.sell(400, 20.00);
fluffy_the_cat.show();
fluffy_the_cat.buy(300000, 40.125);
fluffy_the_cat.show();
fluffy_the_cat.sell(300000, 0.125);
fluffy_the_cat.show();
return 0;
}
-> 일관적이지 않은 숫자 양식
setf()를 사용해 표기상의 문제를 피한다
std::cout.setf(std::ios_base::fixed, std::ios_base::floatfiled);
-> 플래그를 고정 소수점 표기를 사용하기 위해 cout 개체 안에 플래그를 세팅
std::cout.precision(3);
-> cout로 고점 소수점 표기를 사용할 때, 소수점 이하 세 자리까지 보여주도록 세팅
-> 17장. 입력 출력 파일
메서드에 대한 변경 상항을 구현할 때는 클라이언트 프로그램의 다른 부분에 영향을 미치지 않도록
show()가 호출되기 이전의 상태로 정보를 리셋
std::streamsize prec=
std:: cout.precision(3); //정확성을 위해서 이전 값을 저장
...
std::cout.precision(prec); //과거 값으로 리턴
//원본 플래그를 저장
std::ios_base::fmtflags orig=std::cout.setf(std::ios_base::fixed);
...
//저장된 값을 리셋
std::cout.setf(orig, std::ios_base::floatfield);
-> fmtflags : ios_base클래스에 정의된 데이터형
-> orig : 모든 플래그를 보유하고 리셋 구문은 그 정보를 사용해 고정 소수점 표기와 플래그를 포함하고 있는floatfioeld에 있는 정보를 리셋
-> 변화된 내용들이 해당 파일에 한정되고 다른 부분에 영향을 미치지 않는다.
//version 00
#include <iostream>
#include "stock00.h"
void Stock::acquire(const std::string& co, long n, double pr) //해당 회사 주식 첫 취득
// 멤버함수를 정의할 때, 그 멤버 함수가 어느 클래스에 속하는지 나타내는 사용 범위 결정 연산자
{
company = co;
if (n < 0)
{
std::cout << "주식 수는 음수가 될 수 없으므로,"
<< company << " shares를 0으로 설정합니다. \n";
shares = 0;
}
else
shares = n;
share_val = pr;
set_tot();
}
void Stock::buy(long num, double price) //기존 보유 주식의 증가와 감소 관리
{
if (num < 0)
{
std::cout << "매입 주식 수는 음수가 될 수 없으므로, "
<< "거래가 취소되었습니다.\n";
}
else
{
shares += num;
share_val = price;
set_tot();
}
}
void Stock::sell(long num, double price) //기존 보유 주식의 감소 관리
{
using std::cout;
if (num < 0)
{
cout << "모두 주식 수는 음수가 될 수 없으므로, "
<< "거래가 취소되었습니다. \n";
}
else if (num >shares)
{
cout << "보유 주식보다 많은 주식을 매도할 수 없으므로, "
<< "거래가 취소되었습니다. \n";
}
else
{
shares -= num;
share_val = price;
set_tot();
}
}
void Stock::update(double price)
{
share_val = price;
set_tot();
}
void Stock::show()
{
using std::cout;
using std::ios_base;//fmtflags가 ios_base 클래스, std 이름공간에서 정의
//set format #.###
ios_base::fmtflags orig = //orig가 긴 타입 이름이 된다.
cout.setf(ios_base::fixed, ios_base::floatfield);
std::streamsize prec = cout.precision(3);
cout << "회사명: " << company
<< " 주식 수: " << shares << '\n';
cout << " 주가: $" << share_val;
//set format to #.##
cout.precision(2);
cout << " 주식 총 가치: $" << total_val << '\n';
//restore original format
cout.setf(orig, ios_base::floatfield);
cout.precision(prec);
}
클래스 설계
1. 클래스 선언을 제공
class className
{
private:
data member declarations
public:
member function prototype
};
-> private 부분의 멤버는 멤버 함수를 통해서만 접근
-> public 부분에 선언된 멤버들은 클래스 객체를 사용해 직접 접근 [추상화 부분인 public 인터페이스]
2. 클래스 멤버 함수를 구현
멤버함수가 어느 클래스에 속하는지 나타내기 위해 사용 범위 결정 연산자 '::' 를 사용
char* Bozo::Retort()
클래스의 객체를 생성
Bozo bozetta;
클래스 객체를 사용함으로써 클래스 멤버함수를 호출
cout<<bozetta.Retort();
'Programming > C++ 2' 카테고리의 다른 글
[C++] 10장-4. this 포인터 (0) | 2021.04.11 |
---|---|
[C++] 10장-3. 클래스 생성자와 파괴자 (0) | 2021.04.11 |
[C++ 요약] 3장. 데이터 처리 (0) | 2021.04.09 |
[C++] 3장-4. C++ 산술 연산자 (0) | 2021.04.09 |
[C++ 연습문제] 3장. 데이터 처리 (1) (0) | 2021.04.09 |