c++
-
왜 Task 기반의 비동기 프로그래밍인가?Modern C++/Task 기반 비동기 프로그래밍 2020. 8. 27. 21:18
개발을 시작할 때만 해도 C++에서 스레드를 지원하지 않아 이를 직접 개발해서 사용해 왔다. C++ 11 이 후에 스레드가 표준 라이브러리로 추가되었다. 하지만 C++ 도 자바나 Swift, Kotolin과 같이 스레드를 태스크 내부에 숨기고 태스크를 이용해 많은 부분 개발이 된다. 개발자는 더 이상 하드웨어 내 코어의 수에 따라 스레드를 관리하거나 스레드 풀을 구현하고 스레드가 데이터의 관리등을 위해 동기화 처리 문제등에서 조금은 벗어 날 수 있다. C++ 에서 비동기 프로그래밍을 위해서 스레드나 task를 사용한다는 사실은 ModernC++ 을 사용하는 사람은 대부분 알 수 있다. #include #include #include int main() { std::thread t([]() { for (s..
-
스마트 포인터 참조 가이드(Smart Pointer Referece Guide)Modern C++/Smart Pointer 2020. 7. 12. 20:11
1. new를 이용한 동적 객체 생성은 피하되 필요한 경우 스마트 포인터를 사용하라. 스택을 사용하고 할당연산자나 이동/복사 연산을 사용하는게 객체의 수명 관리가 편해 코드가 어떻게 동작하는 지 예측하기 편하다. 동적 할당은 메모리를 힙에 할당하는 데 비용이 드는 것 뿐 만 아니라 메모리의 위치가 연속적이지 않아 컴파일러가 코드의 최적화를 수행하는 데 걸림돌이 되기도 한다. 메모리 할당은 필요할 때만 해야하고 new/delete를 직접 사용하지 않고 스마트 포인터를 사용하면 메모리를 직접 관리해야 하는 부담을 줄일 수 있다. 2. 스마트 포인터 선택 시 가장 먼저 std::unique_ptr 사용을 고려하라. 동적 메모리 할당이 필요한 경우 우선적으로 std::unique_ptr 사용을 고려한다. std..
-
Boost를 이용한 객체 직렬화(Object Serialization)C++ with Boost 2020. 7. 11. 16:12
객체 직렬화 객체 직렬화는 객체를 전송가능한 형태의 연속적인 데이터로 변형하는 것으로 파일로 저장하거나 전송할 때 사용된다. 객체를 연속적인 데이터로 변환하는 과정을 직렬화 연속적인 데이터를 객체로 변환하는 과정을 역직렬화라고 한다. 자바나 C# 은 객체 직렬화를 언어 자체에서 지원하지만 C++은 이를 지원하지 않는다.여기서는 boost의 serialization 컴포넌트를 사용해 직렬화를 구현하는 방법을 살펴본다. Boost 의 객체 직렬화 boost::text_oarchive는 객체를 받아 직렬화를 수행한 후 출력 스트림 객체에 전달한다. 반대로 text_iarchive 는 입력 스트림으로 직렬화된 데이터를 받아 객체로 변환한다. 부스트의 텍스트 입출력 아카이브(text_oarchive, text_i..
-
macOS에서 부스트(Boost)라이브러리 사용하기C++ with Boost 2020. 7. 10. 15:47
Home brew(홈 브루) macOS용 패키지 관리자로 터미널에서 명령을 통해 쉽게 필요한 프로그램을 설치, 삭제, 업데이트 할 수 있다. 이는 RedHat 계열의 리눅스에서 사용하는 yum 이나 Ubuntu 계열의 리눅스에서 사용하는 apt-get과 같다고 생각하면 된다. Home brew 설치 $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" Home brew 업데이트 $ brew update Home brew 삭제 $ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/uninstall)" Ho..
-
1. std::unique_ptrModern C++/Smart Pointer 2020. 7. 2. 18:39
C++ 메모리 관리 C++에서 생 포인터(raw pointer)를 관리하기는 쉽지 않다. 자바는 가비지 콜렉터가 이를 수행하지만 C++같은 경우 사용자가 직접 메모리를 관리해야 한다. 잘못된 메모리 관리는 메모리 릭이 발생하거나 더블 프리 문제로 프로그램이 예외를 던지고 프로그램이 종료하기도 한다. 여기서 생 포인터를 사용하기 어려운 이유를 살펴 보기로 하자. struct Data { uint8_t *data_; size_t length_; }; 여기서 data_는 하나의 객체를 가리키는 포인터인지 배열을 가리키는 포인터인지 코드 자체로는 구별할 수 없다. 생성자에는 uint8_t 형 배열 포인터와 해당 배열의 크기를 받는 생성자와 소멸자를 추가해보자. struct Data { Data(const uin..
-
5. C++11 객체 생성 규칙 Rule of FiveModern C++/Move Semantics 2020. 7. 1. 23:55
C++11 이전 컴파일러가 생성하는 특수 멤버 함수 C++11 이전 컴파일러는 기본 생성자(Basic Constructor), 소멸자(Destructor) , 복사 생성자(Copy Constructor), 복사 할당자(Copy Assignment)를 필요한 경우 자동으로 생성한다. 이는 컴파일 도중 해당 연산을 사용하는 코드가 있는 경우 컴파일러에 의해 암묵적으로 public inline으로 자동으로 생성 된다. class Foo { }; Foo f0; //기본 생성자 생성 Foo f1 = f0; //복사 생성자 생성 Foo f1(f0); //Foo f1 = f0 와 동일 Foo f2; Foo f2 = f0; // 할당 연산자 생성 위의 Foo 클래스는 사용자가 아무것도 정의하지 않았지만 컴파일러가 Fo..
-
4. 이동가능 객체(Movable Type)Modern C++/Move Semantics 2020. 6. 30. 01:15
클래스를 이동 가능하게 만들면 많은 장점들이 있고 이동 가능한 사용자 정의 타입은 표준 라이브러리 유틸과도 잘 동작한다. 이동 연산을 지원하는 클래스를 만드는 경우 코드의 성능, 안정성이나 구현 할 수 있는 방식이 증가한다. 이동 가능한 사용자 타입을 정의하게 되면 표준 라이브리를 사용하는 중에도 이동 연산에 대한 이점을 얻을 수 가 있다. C++11 이전에 컴파일러는 기본 생성자, 소멸자, 복사 생성자, 복사 할당 연산자를 자동으로 추가해 주었는데, C++11 이 후는 여기에 이동 생성자와 이동 할당 연산자가 추가되었다. 여기서는 유리수를 나타내는 Rational 클래스를 통해서 이동 연산이 추가되었을 때 어떤 장점이 있는지 살펴본다. #pragma once #include class Rational ..
-
2. std::moveModern C++/Move Semantics 2020. 6. 29. 17:33
오른쪽 값(R-value)는 외부에서 구별할 수 있는 identity가 없는 임시 객체로 해당 객체의 자원의 소유권을 포기할 수 있다고 생각할 수 있다. int foo() { return 5; } foo(); // 함수 호출 시 int형 임시 값이 생성되지만 코드 범위를 벗어나는 경우 자동 소멸 std::vector v0 { 1, 2, 3, 4, 5 }; auto v1 = v0; // v1 의 복사 생성자 호출 위와 같이 벡터 v1을 v0를 통해서 초기화하고 생성하는 경우 v1의 v0의 내부 버퍼를 강제적으로 복사하게 된다. std::vector get_vector { return std::vector {1, 2, 3, 4, 5}; } auto v2 = get_vector(); // 함수 호출 시 임시 ..