C++ 표준 템플릿 라이브러리 (STL, Standard Template Libraries)
·
C++/Library
표준 템플릿 라이브러리 (STL, Standard Template Libraries) Standard Library와 STL의 차이 STL은 아래 4가지로 구성되어있고, 나머지는 그냥 Standard Library이다. STL 컨테이너 (Containers) STL 반복자 (Iterators) STL 알고리즘 (Algorithms) Functions
따라하며 배우는 C++ 16장
·
C++/TBC++
따라하며 배우는 C++ 16장 표준 템플릿 라이브러리 (Standard Template Libraries) 따라하며 배우는 C++
C++ 순환 의존성 문제 (Circular Dependency Issues)
·
C++/SmartPointer
순환 의존성 문제 (Circular Dependency Issues) 순환 의존성 shared_ptr가 클래스 내부에서 계속 존재하게 되면, 인스턴스가 소멸자를 호출하지 못한다. 만약 인스턴스 두 개가 멤버로 서로를 shared_ptr로 가지고 있다면, 마치 교착 상태처럼 소멸자를 둘 다 호출하지 못하는 상태가 된다. #include #include class Person { std::string name_; std::shared_ptr partner_; public: Person(const std::string& name) : name_(name) { std::cout
C++ weak_ptr
·
C++/Library
weak_ptr weak_ptr 라이브러리 shared_ptr의 순환 의존성 문제를 해결할 수 있다. #include #include class Person { std::string name_; std::weak_ptr partner_; public: Person(const std::string& name) : name_(name) { std::cout
C++ shared_ptr
·
C++/Library
shared_ptr shared_ptr 라이브러리 몇 개의 변수가 포인터를 참조하고 있는지 내부적으로 계산한다. 예제 main.cpp #include #include #include "Resource.h" int main() { Resource* res = new Resource(3); res->setAll(1); { std::shared_ptr ptr1(res); ptr1->print(); { std::shared_ptr ptr2(ptr1); ptr2->setAll(3); ptr2->print(); std::cout print(); std::cout
C++ unique_ptr
·
C++/Library
unique_ptr unique_ptr 라이브러리 scope를 벗어나면 자동으로 메모리를 해제하므로 메모리 누수를 방지할 수 있다. 예제 main.cpp #include #include #include "Resource.h" using namespace std; int main() { std::unique_ptr res(new Resource(100000000)); } /* stdout Resource length constructed Resource destoryed */ Resource.h #pragma once #include class Resource { public: int *data_ = nullptr; unsigned length_ = 0; Resource() { std::cout
C++ std::move
·
C++/Library
std::move 라이브러리 인자로 들어온 값을 R-value로 리턴해준다. 예제 std::move를 사용하지 않은 예제 main.cpp #include #include "Resource.h" #include "AutoPtr.h" using namespace std; int main() { AutoPtr res1(new Resource(10000000)); cout
C++ 이동 생성자와 이동 대입 (Move Constructor and Move Assignment)
·
C++/SmartPointer
이동 생성자와 이동 대입 (Move Constructor and Move Assignment) 속도 비교 L-value 레퍼런스와 R-value 레퍼런스의 성능 차이가 꽤 존재한다. R-value 레퍼런스의 경우 Deep Copy를 하지 않기 때문이다. 생성자, 소멸자를 호출하는 부분이 강의와 살짝 달랐는데, 강의는 Release 모드여서 Debug 모드에 비해 단계가 줄어있는 상태여서 그랬다. 나도 x86버전의 Release모드로 컴파일했더니 실행 파일이 없다는 LNK1104 에러가 발생하였다. 백신 문제였는데, x64로 컴파일하니 실행에 문제는 없었다. 이유는 모르겠다. 아래는 Debug 모드로 실행했다. L-value 레퍼런스를 사용한 예제 Copy Constructor, Copy Assignmen..
C++ 출력 스트림 끊기
·
C++/Library
출력 스트림 끊기 라이브러리 사용 std::cout.rdbuf(streambuf *) using streambuf = basic_streambuf; using _Mysb = basic_streambuf; ... _Mysb* __CLR_OR_THIS_CALL rdbuf(_Mysb* _Strbuf) { // set stream buffer pointer _Mysb* _Oldstrbuf = _Mystrbuf; _Mystrbuf = _Strbuf; clear(); return _Oldstrbuf; } 인자로 입력한 stream buffer pointer를 출력 스트림으로 지정한다. 예제 #include using namespace std; int main() { streambuf* orig_buf = cout...
C++ R-value Reference
·
C++/SmartPointer
R-value Reference R-value L-value와 달리 메모리 주소가 저장되지 않는 값을 의미한다. 예제 주소를 가지고 있지 않은 리터럴 값이나 함수의 반환 값 등을 참조할 수 있다. #include using namespace std; void doSomething(int& ref) { cout
C++ Syntax vs Semantics
·
C++/SmartPointer
Syntax vs Semantics 아래의 코드는 문법(syntax) 상 문제가 없으나, 정수 + 정수와 문자열 + 문자열의 의미(semantics)가 다르다. int x = 1, y = 1; x + y; std::string str1("Hello"), str2(" World"); str1 + str2; Syntax 문법에 잘 맞아서 컴파일이 되는지 Semantics 의미가 무엇인지 Value Semantics (Copy Semantics) Reference Semantics Move Semantics
C++ 스마트 포인터 (Smart Pointer)
·
C++/SmartPointer
스마트 포인터 (Smart Pointer) RAII (Resource Acquisition Is Initialization) C++의 창시자인 스트롭스트룹이 제안한 디자인 패턴이다. C++ RAII(Resource Acquisition Is Initialization)의 해석을 요약하면 다음과 같다. 객체의 유효성에 대해 다음의 관점이 필요하다. 생성이 완료된 객체는 유효한 객체이어야 한다. 즉, 유효하지 않은 객체가 생성되어서는 안 된다. 필요한 자원들을 획득하지 못한 객체는 유효한 객체가 아니다. 대칭성에 의해, 소멸되어서 더 이상 유효하지 않게 된 객체는 어떤 자원도 가지고 있지 않아야 한다. 메모리 누수를 방지하는 기법이다. 동적으로 할당한 메모리, 혹은 파일을 open한 뒤 early retur..
C++ 따라하며 배우는 C++ 15장
·
C++/TBC++
따라하며 배우는 C++ 15장 스마트 포인터 (Smart Pointer) R-value Reference 이동 생성자와 이동 대입 std::move unique_ptr shared_ptr 순환 의존성 문제 (Circular Dependency Issues) 따라하며 배우는 C++
C++ 예외 처리의 위험성과 단점
·
C++/Exception
예외 처리의 위험성과 단점 메모리 누수 throw 이후의 코드는 무시되기 때문에, 메모리 누수가 발생할 가능성이 존재한다. #include using namespace std; int main() { try { int* i = new int[100000]; throw "error"; delete[] i; } catch (...) { cout
C++ 함수 try (Function try)
·
C++/Exception
함수 try (Function try) 함수의 body 자체가 try, catch로 이루어진 경우 함수를 정의할 때 중괄호로 감싸지 않아도 된다고 한다. 잘 쓰이는 문법은 아닌 것 같다. rethrow를 하지 않는다. #include using namespace std; void doSomething() try { throw - 1; } catch (...) { cout
C++ std::exception
·
C++/Library
std::exception 라이브러리 exception 클래스 자식으로 여러 클래스를 가지고 있다. std::exception::what() 함수를 통해 예외 상황을 알 수 있다. 다음과 같이 exception 클래스에서는 가상함수로 정의되어있다. _NODISCARD virtual char const* what() const { return _Data._What ? _Data._What : "Unknown exception"; } https://en.cppreference.com/w/cpp/error/length_error 에 상속 다이어그램이 있으니 참고하면 좋다. #include #include using namespace std; int main() { try { string s; s.resize(..
C++ 예외 클래스와 상속 (Exception Class and Inheritance)
·
C++/Exception
예외 클래스와 상속 (Exception Class and Inheritance) 예외 클래스 예외 상황을 처리할 때 필요한 변수나 함수를 멤버로 가진 클래스 예외 클래스를 사용하지 않은 예제 #include using namespace std; class MyArray { int data_[5]; public: int& operator[] (const int& index) { if (index = 5) throw -1; return data_[index]; } }; void doSomething() { MyArray my_array; try { my_array[100]; } catch (const int& x) { cerr
C++ 스택 되감기 (Stack Unwinding)
·
C++/Exception
스택 되감기 (Stack Unwinding) throw를 통해 던질 경우, 타입에 맞는 catch를 만날 때까지 스택을 되감는다. throw 뒤의 코드는 실행하지 않는다. 마찬가지로 catch를 만나지 못해서 스택을 되감는 경우에도 뒤의 코드를 실행하지 않고 바로 리턴한다. 아래 코드를 디버깅하여 한 줄씩 보면 이해하기 편하다. #include using namespace std; void last() { cout
C++ 예외 처리의 기본
·
C++/Exception
예외 처리의 기본 try, throw, catch try : 코드를 실행할 부분 throw : 예외 상황이 발생하면 해당 정보를 던지는 부분 catch : try 내부에서 throw가 발생했을 경우 이를 받아주는 부분 #include using namespace std; int main() { double x; cin >> x; try { if (x < 0.0) throw string("Negative input"); cout
C++ 예외 처리 (Exception Handling)
·
C++/Exception
예외 처리 (Exception Handling) 예외 처리의 기본 스택 되감기 (Stack Unwinding) 예외 클래스와 상속 (Exception Class and Inheritance) std::exception 함수 try (Function try) 예외 처리의 위험성과 단점
C++ 따라하며 배우는 C++ 14장
·
C++/TBC++
따라하며 배우는 C++ 14장 예외 처리 (Exception Handling) 따라하며 배우는 C++
C++ 멤버 함수를 한 번 더 템플릿화하기
·
C++/Templates
멤버 함수를 한 번 더 템플릿화하기 클래스 템플릿에 있는 멤버 함수를 또 다시 템플릿화할 수 있다. 예제 #include using namespace std; template class A { T value_; public: A(const T & input) : value_(input) {} template void doSomething() { cout
C++ 포인터 템플릿 특수화(Pointer Templates Specialization)
·
C++/Templates
포인터 템플릿 특수화(Pointer Templates Specialization) 템플릿 파라미터가 포인터인 경우 특수화를 하고 싶다면 클래스명에 를 붙여서 작성한다. 예제 #include using namespace std; template class A { T value_; public: A(const T & input) : value_(input) {} void print() { cout
C++ 템플릿 부분 특수화 (Templates Partial Specialization)
·
C++/Templates
템플릿 부분 특수화 (Templates Partial Specialization) 템플릿에서 여러 파라미터를 받을 때, 특정 파라미터만 특수화할 수 있다. 예제 일반 함수 템플릿 부분 특수화 #include using namespace std; template class StaticArray { private: T array_[size]; public: T* getArray() { return array_; } T& operator[](int index) { return array_[index]; } }; template void print(StaticArray& array) { for (int count = 0; count < size; ++count) cout
C++ 클래스 템플릿 특수화 (Class Templates Specialization)
·
C++/Templates
클래스 템플릿 특수화 (Class Templates Specialization) 템플릿의 특정 자료형에 대해서 다르게 처리하고 싶을 때 사용한다. 함수 템플릿 특수화에서는 template을 명시하지 않아도 작동이 됐는데, 클래스 템플릿 특수화에서는 명시하지 않으면 오류가 발생한다. error C2906: &#39;A&#39;: explicit specialization requires &#39;template &#39; 예제 클래스 템플릿 특수화는 다른 클래스를 하나 따로 만들었다고 생각해야 한다. 아래의 예제에서 a_char.test 함수는 존재하지 않는다. 상속과는 엄연히 다르다. #include "MyArray.h" using namespace std; template class A { public..
C++ 함수 템플릿 특수화 (Function Templates Specialization)
·
C++/Templates
함수 템플릿 특수화 (Function Templates Specialization) 템플릿이 있는 상태에서, 특정 자료형에 대해 다른 코드를 실행하고 싶을 때 사용한다. explicit instantiation과 비슷한 느낌인데, 이렇게 정의된 함수는 템플릿에서 따로 인스턴스화하지 않는다고 생각하면 될 것 같다. 예제 #include "MyArray.h" using namespace std; template T getMax(T x, T y) { return (x > y) ? x : y; } template char getMax(char x, char y) { cout y) ? x : y; } int main() { cout
C++ 자료형이 아닌 템플릿 매개변수 (Non-type Templates Parameters)
·
C++/Templates
자료형이 아닌 템플릿 매개변수 (Non-type Templates Parameters) 템플릿 매개변수는 컴파일 타임에 결정되어야 한다. 템플릿의 원리가 여러 경우에 대해 컴파일을 따로 해주는 것이기 때문이다. Non-type 파라미터를 사용할 경우 헤더에서 함수를 정의한다. template와 같이 unsigned int가 온다고 생각해보자. 모든 숫자에 대해 explicit instantiation을 적용할 수는 없으므로 헤더에서 정의하는 것이다. 예제 main.cpp #include "MyArray.h" int main() { MyArray my_array; for (int i = 0; i < my_array.getLength(); ++i) my_array[i] = i * 0.5; my_array.p..
C++ 클래스 템플릿 (Class Templates)
·
C++/Templates
클래스 템플릿 (Class Templates) 클래스에도 템플릿을 적용할 수 있다. 예제 템플릿을 사용하지 않은 예제 main.cpp #include "MyArray.h" int main() { MyArray my_array(10); for (int i = 0; i < my_array.getLength(); ++i) my_array[i] = i * 10; my_array.print(); } /* stdout 0 10 20 30 40 50 60 70 80 90 */ MyArray.h #pragma once #include #include class MyArray { int length_; int* data_; public: MyArray() { length_ = 0; data_ = nullptr; } My..
C++ 함수 템플릿 (Function Templates)
·
C++/Templates
함수 템플릿 (Function Templates) template, template의 형태로 템플릿을 선언할 수 있다. 예제 #include template T getMax(T x, T y) { return (x > y) ? x : y; } class Cents { int cents_; public: Cents(int cents = 0) { cents_ = cents; } bool operator > (const Cents& c) { return (cents_ > c.cents_); } friend std::ostream& operator
C++ 템플릿 (Templates)
·
C++/Templates
템플릿 (Templates) 함수 템플릿 (Function Templates) 클래스 템플릿 (Class Template) 자료형이 아닌 템플릿 매개변수 (Non-type Templates Parameters) 함수 템플릿 특수화 (Function Templates Specialization) 클래스 템플릿 특수화 (Class Templates Specialization) 템플릿 부분 특수화 (Templates Partial Specialization) 포인터 템플릿 특수화(Pointer Templates Specialization) 멤버 함수를 한 번 더 템플릿화하기