Do C++17을 지원하도록 각 프로젝트의 속성에서 아래와 같이 옵션을 추가하라.

/await /std:c++latest

'Language & Toolkit > C++' 카테고리의 다른 글

STL container - other containers  (0) 2019.03.10
STL container - std::list  (0) 2019.03.10
STL container - std::queue & stack  (0) 2019.03.10
STL container - std::map & set  (0) 2019.03.10
STL container - std::vector  (0) 2019.03.09

multi-set

중복 키를 허용하지만 요소를 수정할 수 없다.


multi-map

중복 키를 허용한다.


deque

Double Ended queue로 양쪽 끝에서 삽입 삭제를 허용한다.


priority-queue

자동으로 정렬되는 큐이다.

'Language & Toolkit > C++' 카테고리의 다른 글

visual studio 에서 c++17 지원  (0) 2019.05.03
STL container - std::list  (0) 2019.03.10
STL container - std::queue & stack  (0) 2019.03.10
STL container - std::map & set  (0) 2019.03.10
STL container - std::vector  (0) 2019.03.09

1. std::list 기초

양방향 연결리스트(Double Linked List)로 양쪽 끝에서 삽입 삭제가 가능하다. 따라서 reserver 같은 함수가 있을 수 없다.

operator[] 를 정의할 수 없다.

삽입과 제거에 어디든 가능하고 걸리는 시간이 상수다.


iterator insert(iterator position, const value_type& value)

position 이 가리키는 위치에 삽입.


void push_front(const value_type& value)

처음에 요소 삽입


void push_back(const value_type& value)

마지막에 요소 삽입


void pop_front()

첫번째 요소 삭제


void pop_back()

마지막 요소 삭제


iterator erase(iterator position)

position이 가리키는 요소 삭제


void remove(const value_type& value)

요소와 같은 값을 전부 삭제





'Language & Toolkit > C++' 카테고리의 다른 글

visual studio 에서 c++17 지원  (0) 2019.05.03
STL container - other containers  (0) 2019.03.10
STL container - std::queue & stack  (0) 2019.03.10
STL container - std::map & set  (0) 2019.03.10
STL container - std::vector  (0) 2019.03.09

1. queue 기초

선입선출(First-in, First-out, FIFO) 자료구조이다.


std::queue<string> myQueue;


push(const value_type& val)

요소를 추가한다.


value_type& front()

가장 처음에 삽입되었던 요소를 반환.


value_type& back()

가장 마지막에 삽입되었던 요소를 반환


pop

처음 삽입요소를 삭제한다.


size()

요소의 수를 반환한다.


empty()

queue가 비어있으면 true를 반환한다.


2. stack 기초


후입선출(Last-in, First-out, LIFO) 자료 구조이다.

push(const value_type& val)

요소를 추가한다.


value_type& top()

마지막 삽입되었던 요소를 반환.


pop

마지막 삽입요소를 삭제한다.


size()

요소의 수를 반환한다.


empty()

queue가 비어있으면 true를 반환한다.

'Language & Toolkit > C++' 카테고리의 다른 글

STL container - other containers  (0) 2019.03.10
STL container - std::list  (0) 2019.03.10
STL container - std::map & set  (0) 2019.03.10
STL container - std::vector  (0) 2019.03.09
Beginning C++17 - Chapter 7: Working with Strings  (0) 2019.02.06

1. map 기초

- key, value의 쌍 저장.

- key는 중복될 수 없다.

- 키 기준으로 binary search tree 로 자동 정렬한다.


insert

키는 중복으로 삽입할 수 없고 삽입의 결과 iterator를 반환한다.


operator[]


key 에 대응하는 값을 참조로 반환하고, 키가 없으면 새 요소를 삽입한다.


map<string, int> scoreMap;

int value = scoreMap["coco"]; 일 경우 예외가 발생하진 않으므로 안전하지 않다.


find

키를 기준으로 반복자를 검색한다. 못찾을 경우 end iterator를 반환한다.


swap

두 맵의 키와 값을 바꿔준다.


clear

전체 맵을 삭제한다.


erase

한 요소를 제거한다.


2. set 기초

map과 거의 같지만 key가 아니라 value 자체가 키가 됨으로 중복되지 않아야 한다.


3. map 활용

- 키값으로 클래스를 사용할 수 있지만 정렬을 해야함으로 operator< 연산자를 클래스에 만들어야 한다.

- 다른 사람이 만든 구조체나 클래스를 키로 사용할 경우 연산자를 재정의 할 수 없으므로 별도의 연자 구조체를 만들어야 한다.

struct Comparer

{

bool operator()(const className& left, const className& right) const

{

....

return ...

}

}

1. 기본 함수


reserve 와 resize의 차이.

reserve는 vector의 용량을 늘리는 것으로 적절한 필요 공간을 알경우 새로운 저장 공간 재할당을 막을 수 있으니 잘 사용하자.

실제 값이 할당되는 것은 아니다. 이지 크기가 더 큰 경우에는 용량을 줄여도 허용되지 않는다.


resize는 vector의 크기을 조정하는데 reserve와는 이미 값을 있는 경우에 값을 삭제해 버리니 주의해야 한다.


operator[](size_t n)

지정된 위치의 요소를 참조로 반환한다. 즉 값을 변경할 수 있다.


iterator

STL container 를 순회할 때는 반복자를 쓰는게 좋다.


for(std::vector<int>::iterator iter = scores.begin(0; iter != scores.end(); ++iter)

{

std::cout << *iter << " ";

}


루프를 거꾸로 돌 경우에는 rbegin(), rend() 를 사용한다.


insert

값을 삽입할 수 있다. 아래와 같이 하면 첫번째로 80 이 삽입된다.


std::vector<int>::iterator it = scores.begin();

it = scores.insert(it, 80);


assign

입력값을 연속으로 대입한다. 아래와 같이 하면 숫자 100 이 7개가 추가된다.


vector<int> scores;

scores.assign(7, 100);


swap

두 vector의 값을 서로 교환할 수 있다.


vector<int> scores1;

...

vector<int> scores2;

...


scores1.swap(scores2);


clear

vector를 지운다. 크기는 0이 되지만 용량은 줄이지 않는다.


erase

특정 iterator에 있는 값을 삭제한다.


*iterator

iterator 의 값을 얻을 수 있다. iterator 자체는 포인터 처럼 사용할 수 있다.


2. 사용

- vector 에 개체를 직접 보관할 경우 메모리 복사 발생 시 비용이 높아지게 됨으로 포인터를 저장하는 것이 일반적이다. 물론 이때 메모리 해제를 관리해야 한다.


vector<Score*> scores;

...


for(Score* pScore : scores)

{

delete pScore;

}


scores.cleare();


c++ 이전에 문자열 처리는 단지 null-terminated char현 배열이었다. 이런 불편함을 해결하기 위해 c++에서는 std::string 클래스가 사용된다.



string에서 전통적인 c style의 함수를 사용하기 위해서 두가지 함수가 사용된다. 차이점은 C++ 17부터 data함수가 리턴값으로 const형을 사용하지 않는 char*를 사용할 수 있게 되었다. 역시 함수의 인자로 넘겨줄때 필요할 수 있겠다. 하지만 이와같은 함수는 오로지 기존의 legach c-style의 함수를 사용할 때만 사용해야 할 것이다.



string을 초기화하는 여러가지 방식을 설명한다.

Line 18: brace초기화 방법을 통해 특정 문자열로 바로 초기화 할 수 있다.

Line 21: 생성자 초기화를 통해 임을 글자를 반복하여 초기화 할 수 있다.

Line24: 다른 문자열을 기반으로 임의 영역을 초기화 할 수 있다.



숫자를 스트링으로 변환시 to_string을 이용할 수 있다. 다형성을 지원하여 모든 종류의 숫자를 스트링으로 변형하는데 아쉽게도 아직까지는 자릿수는 지정할 수 없는듯 하다.



스트링 안에 캐릭터들에 접근하여 값을 변경할 수 있다. 샘플 코드에서는 std::toupper 로 사용했었는데. 실제 코드에서는 컴파일 에러가 나서 한참 헤매다가 전역 함수로서 처리하여 테스트를 통과 시켰다.



부분 문자열을 추출하는 함수다. 첫번째 인자로 인덱스 두번째 인자로 count 를 사용할 수 있는제 Line50, 53을 보듯이 count는 범위를 벗어나도 문제가 발생하지 않는다.


스트링은 연산자 재 정의를 통해 비교할 수 있고, Compare함수를 통해 비교할 수 있다. 대신 Compare 함수를 이용하면 좀 더 상세하게 비교할 수 있다. 비교시 인자보다 클경우는 0보다 큰 값을, 동일할 경우 0값을, 작을 경우 0보다 작은 값을 리턴한다. 문자열의 크다, 작다는 각 대응 글자마다 비교하면서 내부 값을 가지고 비교하는 것이다.

포인터에 대한 깊이 있는 설명은 얇은 책 한권은 나올만한 분량일 것이다. 여기서는 간략히 Modern C++에서 추가된 개념에 대해서만 정리하자. 전통적인 포인터 사용법외에 두가지 중요한 포인터 관리 크래스가 추가되었다.




포인터 연산에서 뺄셈은 가능하다. 그 뺄셈은 두 포인터 주소의 차이를 포인터의 크기로 나눈 것인테 ptrdiff_t 형이 추가 되었다. 결국 이것은 내부적으로는 int64나 int형이 재정의된 것이다. 어떤 특별한 장점이 있다기 보다는 포인터의 차이값이란 의미를 강조하기 위한 것으로 보인다.



uniq_ptr 클래스가 추가되었다. 포인터를 유일하게 관리하는 클래스이며 scope를 벗어나면 자동으로 메모리에서 해제가 된다.

라인 15, 16 : 명시적으로 선언하여 메모리를 할당하기 보다는 make_unique를 통해 하는 것을 권장하고 있다. 사실 라인 15에서 선언하는 방식이 문제가 있는 것은 아니지만 함수의 인자로 선언하면서 동시에 할당할 경우 문제를 일을킬 수 있다고 한다. 가급적 라인 16의 방식으로 사용하도록 하자.


라인 20: get 함수를 이용하여 직접적으로 포인터 주소를 가져올 수 있다.

라인 24, 25: release 함수는 포인터 주소를 리턴하면서 객체의 내부 값을 초기화 하는 것이다. 사용자가 직접 메모리를 해제해 주어야 한다. 실질적으로 어떤 경우 이런 함수가 필요한지는 잘 모르겠다. 별로 쓸일이 없을듯. 내부의 메모리를 실질적으로 해제까지 하는 것으로는 reset 함수를 사용하면 된다.



shared_ptr는 포인터를 다른 쉐어드 포인터에 넘겨줄 수 있다. 내부적으로 reference counter를 가지고 있어 모든 공유된 포인터 객체가 범위를 벗어나면 메모리를 해제하게 된다.

라인 36: reference counter를 확인할 수 있다.



레퍼런스는 포인터처럼 직접적으로 주소를 접근하지만 보통의 변수명 처럼 사용할 수 있다. 기존의 C++과 다르지 않은 사용법이지만 새로운 for문을 이용하여 객체 복사를 하지 않고 배열의 값을 변경할 수 있음을 테스트 해보았다.


+ Recent posts