프로그래밍 언어/[ C++ ] 15

[ C++ ] 14. STL 컨테이너

STL 컨테이너 컨테이너(Container)는 다른 객체들을(원소) 보관하는 하나의 커다란 보관소라고 볼 수 있다. 특히, STL 컨테이너는 클래스 템플릿(class template) 의 형태로 구현되어 있기 때문에 임의의 타입의 원소들을 위한 컨테이너를 만들 수 있다. 물론 한 컨테이너에는 한 가지 종류의 객체들만 보관할 수 있다 컨테이너는 자신이 보관하는 원소(element)들의 메모리를 관리하며, 각각의 원소에 접근할 수 있도록 멤버 함수를 제공해준다. 컨테이서 상에서 원소에 접근하는 방법으로 크게 두 가지가 있는데, 하나는 직접 함수를 호출해서 접근하는 것이고, 다른 하나는 반복자(iterator) 을 이용해서 접근하는 것이다. 이에 관해서는 나중에 설명하도록 하겠다. 또한 표준 라이브러리에서는,..

[ C++ ] 13. 생성자

생성자 (Constructor) 클래스의 모든 멤버 변수가 모두 public인 경우 초기화 목록(initialization list) 또는 유니폼 초기화(uniform initialization)를 사용해서 초기화를 직접 초기화할 수 있다. class Foo { public: int m_x; int m_y; }; int main() { Foo foo1 = { 4, 5 }; // initialization list Foo foo2 { 6, 7 }; // uniform initialization (C++11) return 0; } 그러나 멤버 변수가 private인 경우에는 변수에 직접 접근할 수 없는 비공개 상태이므로 더는 위와 같은 방법으로는 클래스를 초기화할 수 없다. 생성자 (Constructor)는..

[ C++ ] 12. 캡슐화

캡슐화 (Encapusulation) 왜 멤버 변수를 비공개(private)로 할까? 이전 포스트 public과 private 접근 지정자에서 멤버 변수는 일반적으로 private로 설정한다고 했다. 왜 이렇게 설정하는지 현실 세계에서 비유를 들어보자. TV에는 TV를 끄고 켜기 위한 리모컨이 있다. 이 리모컨에는 버튼과 휠 등의 TV를 조작할 수 있는 인터페이스(interface)를 제공하지만, 리모컨의 내부가 어떻게 구현되어 있는지는 숨겨져 있다. 리모컨의 버튼을 누르면 리모컨 내부에서 어떻게 동작해서 TV를 조작하는지 알 필요가 없다. 인터페이스와 구현의 분리는 이렇게 리모컨의 작동 방식을 이해하지 않아도 리모컨을 사용할 수 있으므로 효과적이다. 비슷한 이유로, 프로그래밍에서도 구현과 인터페이스의 ..

[ C++ ] 11. public과 private 접근 지정자

public과 private 접근 지정자 다음 구조체를 보자: struct DateStruct // members are public by default { int month; // public by default, can be accessed by anyone int day; // public by default, can be accessed by anyone int year; // public by default, can be accessed by anyone }; int main() { DateStruct date; date.month = 10; date.day = 14; date.year= 2020; return 0; } 위 프로그램에서는 DataStruct*를 선언한 다음 멤버를 직접 초기화하기..

[ C++ ] 10. 클래스와 클래스 멤버

클래스와 클래스 멤버 객체 지향 프로그래밍에서, 우리는 종종 우리의 타입이 데이터를 보유할 뿐만 아니라, 데이터와 함께 작동하는 기능을 제공하기를 원한다. C++에서는 이 작업을 class 키워드를 통해 수행한다. class 키워드를 사용하면 클래스라고 하는 새로운 사용자 정의 타입을 정의할 수 있다. 클래스 (class) C++에서 클래스와 구조체는 본질적으로 같다: struct DateStruct { int year; int month; int day; }; class DateClass { public: int m_year; int m_month; int m_day; }; 중요한 차이점은 클래스의 public 키워드뿐이다. 이것은 다음 포스트에서 자세히 설명할 예정이다. 구조체 선언과 마찬가지로, 클..

[ C++ ] 09. std::vector의 capacity 및 stack 동작

std::vector의 capacity 및 stack 동작 이전 포스트에서 std::vector가 동적 배열이라는 것을 이야기했다. std::vector는 가장 유용하게 많이 사용되므로 다른 속성과 기능에 대해서 좀 더 이야기해보자. Length vs. Capacity int* array = new int[10] { 1, 2, 3, 4, 5 }; 위 예제 코드는 요소 5개만 할당하였어도 배열의 길이는 10이라고 말할 수 있다. 초기화한 요소만 사용하고, 사용하지 않는 요소들을 미래에 확장하기 위해 남겨두기 위해서는 어떻게 해야 할까? 위 예제에서는 할당된 요소 수에서 "사용하는" 요소 수를 별도로 기억해야 한다. int* array = new int[10] { 1, 2, 3, 4, 5 }; // 미래에 ..

[ C++ ] 08. 스택과 힙(Stack & Heap)

스택과 힙 (Stack and Heap) 프로그램이 사용하는 메모리는 일반적으로 세그먼트(segment)라고 하는 몇 가지 다른 영역으로 나뉜다. 코드 세그먼트 : 컴파일된 프로그램이 저장되는 영역, 일반적으로 read-only 속성이다. 데이터 세그먼트 : 전역 변수 및 정적 변수가 저장되는 영역 힙 세그먼트 : 동적으로 할당된 변수가 할당되는 영역 스택 세그먼트 : 함수 매개 변수, 지역 변수 및 기타 함수 관련 정보가 저장되는 영역 힙 세그먼트 (Heap segment) 힙 세그먼트는 동적 메모리 할당에 사용되는 메모리를 추적한다. C++에서 new 연산자를 사용해서 메모리를 할당하면 이 메모리는 응용 프로그램의 힙 세그먼트에 할당된다. int* ptr = new int; // ptr은 힙에서 4바..

[ C++ ] 07. 함수 포인터

함수 포인터 (function pointer) 포인터가 다른 변수의 주소를 저장하는 변수라는 것을 배웠다. 이와 유사하게 함수 포인터(function pointer)는 함수를 가리키는 변수다. 즉, 함수의 주소를 저장하는 변수다. int foo() { return 5; } 식별자 foo는 함수의 이름이다. 그러나 함수의 타입은 무엇일까? 함수는 고유한 l-value 함수 타입이다. 위 예제의 경우 정수(int)를 반환하고 매개 변수를 받지 않는 함수 타입이다. 변수와 마찬가지로 함수는 메모리의 할당된 주소에 있다. () 연산자를 통해 함수를 호출하면, 호출되는 함수의 주소로 점프하여 실행한다. int foo() // foo 코드는 메모리 주소 0x002717f0에서 시작한다. { return 5; } i..

[ C++ ] 05. std::vector

std::vector 이전 포스트에서 std::array를 소개했다. std::array는 C++의 내장 고정 배열(fixed array) 기능을 더 안전하고 유용한 형태로 제공한다. 마찬가지로 C++ 표준 라이브러리에는 동적 배열(dynamic array) 작업을 더 안전하고 쉽게 해주는 std::vector를 제공한다. An introduction to std::vector C++ 03에서 소개된 std::vector는 자체 메모리 관리를 처리하는 동적 배열 기능을 제공한다. 즉, new와 delete를 사용하여 메모리를 동적으로 할당∙해제하지 않고도 런타임에 길이가 설정된 배열을 만들 수 있다∙ std :: vector는 헤더에 정의되어 있다. std::vector 변수 선언은 쉽다. #includ..

[ C++ ] 04. std::array

std::array 이전 포스트들에서 고정 배열(fixed array)과 동적 배열(dynamic array)을 배웠다. 두 가지 배열 모두 C++에 내장되어 있지만, 포인터로 형 변환되었을 시 배열 길이 정보가 손실되고, 동적 배열은 지저분한 할당 해제 문제가 있다. 이러한 문제를 해결하기 위해 C++ 표준라이브러리는 배열 관리를 쉽게 해주는 std::array 와 std::vector가 있다. An introduction to std::array in C++11 C++ 11에서 소개된 std::array는 함수에 전달할 때 포인터로 형 변환되지 않는 고정 길이 배열이다. std:: array는 헤더의 std 네임 스페이스 내부에 정의되어 있다. std::array 변수 선언은 쉽다. #include ..

[ C++ ] 03. auto

auto C++ 11에서 타입 추론 (Type inference in C++ 11) C++ 11에서 auto 키워드는 유용하다. double d = 5.0; 5.0이 부동 소수점 숫자 리터럴이라는 것을 이미 알고 있다면, 왜 d의 타입(=자료형)을 double이라고 명시적으로 선언해야 할까? 변수를 초기화할 때 사용하는 값을 기준으로 적절한 타입을 추론하도록 하면 편하지 않을까? auto 키워드는 선언된 변수의 초기화 식을 사용하여 해당 형식을 추론하도록 컴파일러에 지시한다. 즉, auto 키워드를 사용하면 초깃값의 형식에 맟춰 선언하는 인스턴스(변수)의 형식이 '자동'으로 결정된다. 이것을 타입 추론(type inference)이라고 한다. auto d = 5.0; // 5.0 is a ..

[ C++ ] 02. 난수 생성

난수 생성 (Random number generation) 랜덤 숫자(=난수)를 생성하는 기능은 특정 종류의 프로그램에서 유용하다. 예를 들어 게임에서 무작위 이벤트가 없다면 몬스터들은 항상 같은 방법으로 공격하고, 항상 같은 아이템을 얻을 것이다. 던전의 레이아웃 또한 절대 바뀌지 않을 것이다. 그러면 어떻게 난수를 생성해야 할까? 현실에서는 동전 뒤집기, 주사위 굴리기, 카드 패 돌리기 등의 방법으로 무작위 결과를 만든다. 이러한 이벤트는 물리적 변수(Ex. 중력, 마찰, 공기 저항, 운동량)를 많이 포함한다. 그러나 컴퓨터는 물리적 변수를 이용하도록 설계되지 않았으므로 컴퓨터는 동전을 던지거나 주사위를 굴릴 수 없다. 컴퓨터는 모든 것이 바이너리이고 제어된 전기 환경에서 살고 있다. 컴퓨터는 본질적..

[ C++ ] 01. 부동 소수점 숫자

부동 소수점 숫자 (floating point numbers) 정수(integer)도 매우 좋지만 때때로 매우 큰 숫자나 소수점이 있는 숫자를 저장해야 하는 경우도 있다. 부동 소수점(floating point) 자료형 변수는 4320.0, -3.33, 0.01226과 같은 실수를 저장하는 변수다. 부동 소수점은 소수점이 "부동(float)" 할 수 있다는 것을 의미한다. 즉, 소수점 앞과 뒤에 있는 자릿수를 지원한다. C++에는 float, double 및 long double 과 같은 부동 소수점 자료형이 있다. 정수와 마찬가지로 C++은 이러한 자료형의 크기를 지정하지 정의하지 않았다. 현대 아키텍처에서 부동 소수점 표현은 거의 항상 IEEE 754 바이너리 형식을 따른다. 이 형식에서 float은..