본문 바로가기

Prog. Langs & Tools/C++

[C++] Ch14. C++ 최신 문법 - Part2

지난 포스팅에 이어서 C++ 최신 버전에서 추가된 문법들에 대해서 공부한 내용을 정리해 보려고 한다.

 

새로운 자료형

nullptr

NULL을 쓰면 가끔 이상한 일이 발생된다. C++에서 NULL은 어떤 타입이 아니라 0이다. 따라서 함수를 호출할 때 적합하지가 않다. 따라서 nullptr가 등장하였다. nullptr는 null 포인터 상수이다. nullptr는 다음과 같이 사용할 수 있다.

// Main.cpp
Class* myClass = new Class("COMP3200");

const Student* student = myClass->GetStudent("Coco");
if (student != nullptr)
{
	std::cout << student->GetID() << ":" << student->GetName() << std::endL;
}

 

고정폭 정수형

아래 자료형들의 바이트 크기는 얼마일까?

  • char : 1 byte
  • short : 2 byte
  • long : 4 byte
  • long long : 8 byte
  • int : 4 byte

사실 int가 4 byte여야 한다는 표준은 따로 없다. 컴파일러를 만드는 사람과 언어 스펙을 만드는 사람이 달라서 이러한 것들을 우리는 외워서 쓸 수 밖에 없다.

C++에서 고정폭 정수형을 지원하게 되었다.

  • int8_t / uint8_t
  • int16_t / uint16_t
  • int32_t / uint32_t

.. 등등 더 많이 있다. 가독성 향사을 위해 낡은 기존 자료형보다 이것들을 쓰자.

int8_t score = student->GetScore();

 

enum class

Typescript에서도 있는 enum은 어떤 값들을 int로 바꾸어 주는 타입과 같은 역할을 한다. C++11에서는 enum class를 지원하기 시작했다. 정수형으로의 암시적인 캐스팅이 없다. 자료형을 검사하며, enum에 할당할 바이트 양을 정할 수 있다.

// Class.h
#include <cstdint>
enum class eScoreType : uint8_t
{
    Assignment1,
    Assignment2,
    Assignment3,
    Midterm,
    Final = 0x100, // 경고!
};

위의 코드는 enum을 8bit에 넣으려고 한다. 그렇기 때문에 Final의 0x100은 overflow가 일어나서 0을 반환한다는 경고 문구를 뱉는다.

 

새로 추가된 STL

정렬 안 된 맵(unordered_map)

우리는 map 컨테이너를 배웠다. map의 경우 자동으로 정렬이 되는 컨테이너이다. 그래서, 요소 삽입/제거가 빈번할 경우 성능이 저하될 수 있다. 이 map을 정렬 안 하고 쓸 수는 없어서 정렬 안 된 맵(unordered_map)이 나오게 되었다.

unordered_map은 키와 값의 쌍을 저장한다. 키는 중복할 수 없다. 자동으로 정렬되지 않는 컨테이너로 탐색 시 O(1)으로 값을 찾는다.(해시 충돌이 없는 경우, 최악의 경우 O(n)까지 갈 수도 있다.) 요소는 해쉬 함수가 생성하는 색인(index)기반의 버킷들로 구성된다. 해쉬맵(hashmap) 이라고도 한다.

해시 맵에서는 다음과 같이 요소를 탐색하기 때문에 어떠한 키 값이 주어지든지, 해시 함수를 통해 인덱스 값을 받아서 바로 버킷의 위치를 찾을 수가 있다. 물론 해시 충돌이 없다는 가정 하에서이다.

unordered_set도 map과 비슷한 이유로 만들어지게 되었다.

 

어레이(array)

STL 클래스로서 array가 추가되었다. FixedVector 템플릿 클래스와 비슷하다. 요소 수를 기억하지 않는다. 단순히 C 스타일 배열을 추상화한 것으로 이해하면 된다.

FixedVector<int, 3> numbers;

numbers.Add(1);
std::cout << numbers.GetSize() << std::endL; // 1
std::cout << numbers.GetCapacity() << std::endL; // 3
#include <array>
// ...
std::array<int, 3> numbers;

numbers[0] = 1;
std:cout << numbers.size() << std::endL; // 3
std:cout << numbers.max_size() << std::endL; // 3

 

범위 기반 for 반복문

자바스크립트에서도 있는 for 문 및 forEach 와 비슷한 문법이므로 생략한다.

 

참고자료

  1.  <C++ 언매니지드 프로그래밍> 포큐 아카데미