네임스페이스, 클래스, 멤버 함수, stdio 스트림, 초기화 목록, static, const 등
내부 식별자의 유효 범위를 정해주는 것
namespace
키워드를 사용하여 정의
std
네임스페이스 내부에 선언되어 있음// namespace.h
namespace bono
{
int count;
}
namespace hello
{
int count;
}
범위 지정 연산자(scope resolution operator) ::
를 사용하여 접근
// namespace.cpp
#include "namespace.h"
int main(void)
{
bono::count = 1;
hello::count = 2;
}
https://blog.hexabrain.net/167
구조체의 상위 호환
메모리에 대입된 클래스 타입의 객체
실생활의 물체에 대해 그 행동(behavior)과 상태(state)를 구체화하는 프로그래밍
https://hwan-shell.tistory.com/226
std::cout << 출력할데이터;
std::cin >> 저장할변수;
cin
객체는 사용자가 입력한 데이터를 오른쪽에 위치한 변수 타입과 동일하게 변환시켜줌<<
: 삽입 연산자>>
: 추출 연산자초기화 목록
생성자에서 필드를 간단하게 초기화하는 방법
int value = 5;
int value(5);
생성자 초기화 목록
class Test
{
int m_a;
int m_b;
public:
Test(int a, int b): m_a(a), m_b(b) {}
}
상수(값을 변경할 수 없는 변수)
const int* ptr
: 변수가 가리키는 값에 대하여 상수화int* const ptr
: 포인터 자체를 상수화const int* const ptr
로 사용할 수도 있음const
를 붙임int getNum(void) const {}
c++
와 -Wall -Wextra -Werror
플래그로 컴파일-std=c++98
플래그를 추가해도 컴파일되어야 함*printf()
, *alloc()
, free()
사용 금지using namespace <ns_name>
, friend
사용 금지new
키워드 사용 후 메모리 누수 잘 체크하기iostream cout
사용해보기
* LOUD AND UNBEARABLE FEEDBACK NOISE *
출력\n
) 대신 std::endl
사용\n
은 버퍼를 사용하기 때문에 바로 출력이 되지 않을 수도 있음cctype
의 toupper
사용int
로 받기 때문에 타입 캐스팅을 해주어야 함static_cast<타입>
연산자 사용(char)
처럼 변환하는 것과 달리 컴파일 타임에 오류를 잡아줌$>./megaphone "shhhhh... I think the students are asleep..."
SHHHHH... I THINK THE STUDENTS ARE ASLEEP...
$>./megaphone Damnit " ! " "Sorry students, I thought this thing was off."
DAMNIT ! SORRY STUDENTS, I THOUGHT THIS THING WAS OFF.
$>./megaphone
* LOUD AND UNBEARABLE FEEDBACK NOISE *
$>
동적 할당 없이(new
쓰지 않고) 클래스 만들고 사용해보기
string
, iomanip
사용해보기
PhoneBook
Contact
: 연락처 클래스프로그램 시작 시 전화번호부는 비어 있고, 사용자에게 아래의 명령어 중 하나를 입력받음
하나의 명령어를 수행한 후 다시 명령어 입력받기
ADD
: 새로운 연락처 저장SEARCH
: 특정 연락처 출력|
로 구분, 오른쪽 정렬.
으로 치환해서 자르기EXIT
: 프로그램 종료http://www.cplusplus.com/reference/string/string/
http://www.cplusplus.com/reference/iomanip/
setw()
size()
substr()
cin에 int가 아닌 문자가 들어올 때 제대로 동작하지 않는 오류
https://literate-t.tistory.com/69
int num; std::cin >> num;
위와 같은 코드가 있을 때 유효하지 않은 입력값이 들어오면 cin에 failbit가 켜지고 더이상 cin에 입력을 받을 수 없게 된다고 함
이후 입력을 위해서는 플래그를 초기화하고 버퍼의 내용을 모두 삭제하여 스트림을 복구해야 함
string 메모리 관리
https://smoothiecoding.kr/cpp-dynamical-string/
https://ha-young.github.io/2020/cpp/2020-08-05-C++-String-%EB%AC%B8%EC%9E%90%EC%97%B4/
C++에서 string은 클래스로 관리되는데 자동으로new
와delete
를 실행해준다고 함
👉 따로 메모리를 관리할 필요가 없음
cin에 공백 입력이 들어오면 다음 입력을 건너뛰는 오류
https://kyu9341.github.io/C-C/2020/01/17/C++getline()/
<string>
의getline()
사용
주의! 이전에cin
으로 입력을 받았다면 개행 문자가 버퍼에 남아 있어서 입력으로 간주하기 때문에cin.ignore()
를 호출하여 버퍼에 남아 있는 내용을 무시해야 함
헤더와 로그 파일을 참고하여 Accout.cpp 작성
뒤에서 사용하는 과제가 있으니까 여기서 굳이 깊게 살펴볼 필요는 없을 듯
임의 타입의 객체 보관
(vector, list, deque가 있는데 이번 과제에서는 vector 사용)
begin()
과 end()
를 사용하여 반복자를 얻을 수 있음begin()
: 첫 번째 원소를 가리킴end()
: 마지막 원소 하나 뒤를 가리킴 (비어 있는 벡터를 표현하기 위해 이렇게 설계됨)컨테이너 원소에 접근할 수 있는 포인터와 같은 객체
iterator
멤버 타입으로 정의되어 있음std::pair
첫 번째로 들어온 값을 first
, 두 번째로 들어온 값을 second
멤버 변수로 갖는 클래스
std::for_each
시작 지점과 끝 지점을 가리키는 반복자를 받아서 인자로 주어진 함수를 순차적으로 실행
Function for_each (InputIterator first, InputIterator last, Function fn);
std::for_each( acc_begin, acc_end, std::mem_fun_ref( &Account::displayStatus ) );
fn
은 void(T&)
std::mem_fun_ref
: 특정 객체의 멤버 함수를 래핑할 때 사용?ctime
사용
time()
으로 현재 시간 받아오기time_t
: 밀리세컨드 단위time_t time (time_t* timer);
localtime()
으로 현재 지역 시간으로 변환 가능struct tm
구조체에 정보 저장struct tm * localtime (const time_t * timer);
strftime()
으로 포맷 지정 가능ptr
: 문자열을 저장할 버퍼maxsize
: ptr
에 복사될 최대 문자 수 (널문자 포함)format
: 형식 지정 문자열timeptr
: struct tm
포인터size_t strftime (char* ptr, size_t maxsize, const char* format, const struct tm* timeptr );
[19920104_091532] index:0;amount:42;created
[19920104_091532] index:1;amount:54;created
[19920104_091532] index:2;amount:957;created
[19920104_091532] index:3;amount:432;created
[19920104_091532] index:4;amount:1234;created
[19920104_091532] index:5;amount:0;created
[19920104_091532] index:6;amount:754;created
[19920104_091532] index:7;amount:16576;created
typedef std::vector<Account::t> accounts_t;
int const amounts[] = { 42, 54, 957, 432, 1234, 0, 754, 16576 };
size_t const amounts_size( sizeof(amounts) / sizeof(int) );
accounts_t accounts( amounts, amounts + amounts_size );
Account
생성자를 호출한 뒤 각 인스턴스를 accounts_t
vector에 저장Account
의 생성자가 int
를 받도록 되어 있음Account( int initial_deposit );
displayAccountsInfos()
[19920104_091532] accounts:8;total:20049;deposits:0;withdrawals:0
static void displayAccountsInfos( void );
Account
의 static 멤버 변수들 출력displayStatus()
[19920104_091532] index:0;amount:42;deposits:0;withdrawals:0
[19920104_091532] index:1;amount:54;deposits:0;withdrawals:0
[19920104_091532] index:2;amount:957;deposits:0;withdrawals:0
[19920104_091532] index:3;amount:432;deposits:0;withdrawals:0
[19920104_091532] index:4;amount:1234;deposits:0;withdrawals:0
[19920104_091532] index:5;amount:0;deposits:0;withdrawals:0
[19920104_091532] index:6;amount:754;deposits:0;withdrawals:0
[19920104_091532] index:7;amount:16576;deposits:0;withdrawals:0
std::for_each( acc_begin, acc_end, std::mem_fun_ref( &Account::displayStatus ) );
Account
인스턴스의 멤버 변수 출력makeDeposit()
, makeWithdrawal()
[19920104_091532] index:0;p_amount:42;deposit:5;amount:47;nb_deposits:1
[19920104_091532] index:1;p_amount:54;deposit:765;amount:819;nb_deposits:1
[19920104_091532] index:2;p_amount:957;deposit:564;amount:1521;nb_deposits:1
[19920104_091532] index:3;p_amount:432;deposit:2;amount:434;nb_deposits:1
[19920104_091532] index:4;p_amount:1234;deposit:87;amount:1321;nb_deposits:1
[19920104_091532] index:5;p_amount:0;deposit:23;amount:23;nb_deposits:1
[19920104_091532] index:6;p_amount:754;deposit:9;amount:763;nb_deposits:1
[19920104_091532] index:7;p_amount:16576;deposit:20;amount:16596;nb_deposits:1
...
[19920104_091532] index:0;p_amount:47;withdrawal:refused
[19920104_091532] index:1;p_amount:819;withdrawal:34;amount:785;nb_withdrawals:1
[19920104_091532] index:2;p_amount:1521;withdrawal:657;amount:864;nb_withdrawals:1
[19920104_091532] index:3;p_amount:434;withdrawal:4;amount:430;nb_withdrawals:1
[19920104_091532] index:4;p_amount:1321;withdrawal:76;amount:1245;nb_withdrawals:1
[19920104_091532] index:5;p_amount:23;withdrawal:refused
[19920104_091532] index:6;p_amount:763;withdrawal:657;amount:106;nb_withdrawals:1
[19920104_091532] index:7;p_amount:16596;withdrawal:7654;amount:8942;nb_withdrawals:1
for ( acc_int_t it( acc_begin, dep_begin );
it.first != acc_end && it.second != dep_end;
++(it.first), ++(it.second) ) {
(*(it.first)).makeDeposit( *(it.second) );
}
...
for ( acc_int_t it( acc_begin, wit_begin );
it.first != acc_end && it.second != wit_end;
++(it.first), ++(it.second) ) {
(*(it.first)).makeWithdrawal( *(it.second) );
}
accounts
와 deposits
둘 다 마지막이 아닐 때까지 하나씩 순회Account
인스턴스의 멤버 함수인 makeDeposit
의 인자로 현재 가리키는deposit
을 순서대로 전달하여 호출withdrawals
도 동일refused
int checkAmount( void ) const;
사용프로그램이 종료될 때 자동으로 호출됨
[19920104_091532] index:0;amount:47;closed
[19920104_091532] index:1;amount:785;closed
[19920104_091532] index:2;amount:864;closed
[19920104_091532] index:3;amount:430;closed
[19920104_091532] index:4;amount:1245;closed
[19920104_091532] index:5;amount:23;closed
[19920104_091532] index:6;amount:106;closed
[19920104_091532] index:7;amount:8942;closed
~Account( void );
private에 있는 기본 생성자
C++98에서 기본 생성자, 대입 연산자, 복사 생성자, 소멸자를 작성하지 않으면 자동으로 정의되어 호출할 수 있게 됨
👉 이를 막으려면 외부에서 접근하지 못하도록 private으로 빼야 함
(이번 서브젝트에서 기본 생성자를 호출하지 않기 때문에 안에 구현할 내용은 없음)
static 멤버 변수를 인식하지 못하는 오류
https://stackoverflow.com/questions/9282354/static-variable-link-error
Undefined symbols for architecture arm64: "Account::_totalAmount", referenced from: Account::getTotalAmount() in Account.o Account::displayAccountsInfos() in Account.o Account::Account(int) in Account.o Account::makeDeposit(int) in Account.o ...
static 멤버 변수는 전역에서 정의를 하고 사용해야 한다고 함!
Makefile
https://skm1104.tistory.com/m/86
https://bigpel66.oopy.io/library/42/inner-circle/11
https://velog.io/@appti/CPP-Module-00-ex01