앞서 살펴본 스마트 포인터들 중에서 가장 이해하기 어려운 것이 weak_ptr 이다. unique_ptr 와 shared_ptr 는 목적이 분명하지만 weak_ptr 는 경험하지 않는다면 언제 써야하는지 알기 어렵다. 이 포스트에서 weak_ptr 를 사용해야하는 경우를 살펴보자. 사용법 weak_ptr 는 언제든 소멸될 수 있는 객체를 사용할 때 쓰는 스마트 포인터이다. weak_ptr 는 shared_ptr 와 함께 사용하는 스마트 포인터이지만 reference_count 를 증가시키지 않는다. 다시 말하면 객체의 소멸에 관여하지 않는다는 뜻이다. 그로 인한 문제로 사용하려고 하는 순간 이미 객체가 소멸될 수도 있는 것이다. 만약 객체를 사용할 때, 객체가 소멸되는 경우 crash 가 발생하게 되는 ..
shared_ptr의 특징 C 와 C++ 를 프로그래밍을 하다보면 가장 어려운 점이 바로 메모리 관리이다. 이전 항목에서 배운 unique_ptr 를 사용하면 자동으로 메모리를 해주기는 하지만 여러 객체에서 소유하는 경우에는 unique_ptr 를 사용할 수 없다. 이때 사용할 수 있는 스마트 포인터가 shared_ptr 이다. shared_ptr 는 객체의 소멸시점을 관리하기 위하여 reference count 를 사용한다. 이 reference count 가 0 이 되면 메모리를 해제하게 된다. shared_ptr 는 내부적으로 다음과 같이 구현되어 있다. shared_ptr의 크기는 생 포인터의 두 배이다. 생 포인터의 크기와 reference count 를 가르키는 포인터를 갖고 있어야 하기 때문..
서론 AddMovementInput 함수를 사용하다보면 의도치않게 문제가 발생한다. 언리얼 엔진4 도큐먼트에서 제공하는 코드에서도 문제가 발생하는것을 볼 수 있다. 발생하는 문제는 두가지가 있다. 보는 방향에 따라 이동속도가 다름 대각선으로 이동시 속도가 빨라짐 문제를 설명하기 위해 공식 문서에서 사용하는 예제를 가져왔다. 2.3 - 캐릭터 동작 함수 구현 일인칭 슈팅 캐릭터에 대한 동작 함수 구현법을 배워봅니다. docs.unrealengine.com 위의 도큐먼트에서 구현한 코드는 다음과 같다. // 입력에 함수성 바인딩을 위해 호출됩니다. void AFPSCharacter::SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent)..
std::unique_ptr 는 독점적 소유권 의미론을 재현하는 클래스이다. 그에 따라 복사를 허용하지 않으며, 오직 이동만 가능하다. std::unique_ptr 는 raw 포인터와 거의 같은 크기를 갖는다. 메모리와 CPU 성능이 넉넉하지 않더라도 사용하기에 충분하다는 뜻이다. std::unique_ptr 객체는 자신이 파괴될 때, 가르키는 자원 또한 함께 파괴된다. std::unique_ptr 가 파괴될 때 수행되는 커스텀 삭제자를 사용할 수 있다. 팩터리 패턴의 함수의 예시를 살펴보자. auto delInvmt = [](Investment* pInvestment) { makeLogEntry(pInvestment); delete pInvestment; }; template std::unique_pt..
C++ 에서 말하는 특수 멤버 함수란 C++ 이 스스로 작성하는 멤버 함수들을 가리킨다. 대표적으로 기본 생성자, 소멸자, 복사 생성자 등이 있다. 이 함수들이 생성되기 위한 가장 기본적인 조건은 클라이언트 코드에서 이 함수들을 사용할 때 생성된다. C++11 에 오면서 두 가지의 특수 멤버 함수가 추가됐다. 이 특수 멤버 함수의 조건을 알아보자. 이동 생성자와 이동 배정 연산자 C++ 의 가장 큰 특징이 바로 move semantics 이다. 이와 관련하여 이동 생성자와 이동 배정 연산자가 추가되었다. 이 둘은 아래와 같이 정의된다. class Widget { public: ... Widget(Widget&& rhs); Widget& operator=(Widget&& rhs); ... }; 두 특수 멤..
멤버 함수가 멤버 변수들을 수정하지 않는다면 const 로 선언하는 것이 자연스럽다. 그런데 스레드를 사용한다면 문제가 생길 수 있다. 예시를 통해 살펴보자. mutex의 사용 다음은 다항식의 근을 구는 함수 roots 를 구현하는 상황이다. 성능 향상을 위해 캐싱을 이용하였으며, rootsAreValid 의 값을 이용하여 캐싱 여부를 판별하는 함수이다. class Polynomial { public: using RootsType = std::vector; RootsType roots() const { if(!rootsAreValid) { ... rootsAreValid = true; } } private: mutable bool rootsAreValid{ false }; mutable RootsType..
constexpr 은 객체에 적용했을때는 const 가 되며, 이 값은 컴파일 시점에 알려진다. 컴파일 시점에 알려지는 값들은 읽기 전용 메모리에 배치될 수 있다. 또 다른 장점으로는 컴파일 시점에 정수 상수 표현식이 요구되는 문맥에서 사용할 수 있다는 것이다. 어떤 경우에 사용할 수 있는지 예제를 통해 알아보자. int sz; // 비 constexpr 변수 ... constexpr auto arraySize1 = sz; // error std::array data1; // error constexpr auto arraySize2 = 10; // 10은 상수 std::array data2; // arraySize2는 constexpr 객체 여기서 알아야할것은 constexpr 이 아닌 const 로 선..
서론 noexcept 를 이해하기 전에 C 와 C++ 의 특징에 대해서 알고가는 것이 좋을것 같아 작성한다. C 는 하드웨어를 작성하기 위해 만들어진 언어이다. 그러다보니 프로그래머에게 많은 자유를 주어진다. 예를 들어 다른 언어와 다르게 메모리를 직접 관리할 수 있으며, 하드웨어 제어 또한 가능하다. 대신에 그로 인해 발생하는 댕글링 포인터와 같은 문제에 대해서는 책임지지 않는다. 이러한 특성이 C++ 에도 전달되어서인지 예외에 대한 책임은 온전히 프로그래머의 몫이다. 그로인한 특성으로 try catch 문이 문법으로 존재함에도 STL에서 try catch 문을 사용하지 않는다. 또한 예외에 대해 변경이 생긴다면 기존에 존재하던 프로그램에 문제를 일으킬 수 있다는 이유로 try catch 문과 같은 예..
- Total
- Today
- Yesterday
- C++14
- Override
- 다이소
- const
- async
- 보편참조
- 포인터
- 람다
- CPP
- Perfect
- std::forward
- detach
- C++11
- 발아시기
- Forwarding
- thread
- MOVE
- C++
- Future
- forward
- Overloading
- 보편 참조
- Modern
- Effective Modern C++
- C
- auto
- Effective
- Join
- std::move
- Unreal
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |