일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- HTML
- 구조체
- c# 윈폼
- C언어 포인터
- github
- 깃
- Python
- 유니티
- C# delegate
- Data Structure
- C++
- jupyter
- c#
- docker
- c언어
- 플러터
- Unity
- Algorithm
- 도커
- Flutter
- Houdini
- c# winform
- gitlab
- dart 언어
- jupyter lab
- 다트 언어
- git
- c# 추상 클래스
- vim
- 포인터
- Today
- Total
목록Programming/C++ (52)
nomad-programmer
프로그래밍은 예측불허의 여정이다. 코드가 실행되는 동안 예외 상황은 피할 수 없고, 심지어 예외 처리 메커니즘도 때로는 예외를 처리하지 못할 수 있다. noexcept와 set_terminate를 활용해 예외 처리와 예외 처리 실패에 대응하고 프로그램의 안정성과 신뢰성을 높이는 방법을 알아보자.예외 처리 생략 - noexcept함수에서 문제가 발생할 때 반드시 예외를 발생시켜야 하는 것은 아니다. 때로는 예외를 발생시키는 것이 득보다 실이 더 클 때도 있다.오류와 예외는 엄연히 다르다. 값이나 실행 흐름을 충분히 예측할 수 있을 때는 if문으로 처리하는 것이 성능 면에서 훨씬 이득이다.함수가 예외를 던지지 않음을 나타낼 때는 다음처럼 noexcept 키워드로 명시할 수 있다. 이처럼 함수가 예외를 던지지..
기본으로 제공되는 리터럴 외에 개발자가 리터럴을 직접 정의할 수도 있다. 리터럴을 나타내는 접미사를 함수 이름으로 만들면 되는데, 다음처럼 사용자 정의 리터럴 연산자 operator"" 를 사용한다.반환_타입 operator"" 러터럴_접미사(매개변수) 이렇게 하면 해당 접미사를 붙인 값은 사용자가 정의한 값으로 바꿔서 사용할 수 있다. 다음 코드는 마일(mile)과 킬로미터(kilometers) 단위를 리터럴로 정의한 예이다.#include using namespace std;const long double km_per_mile = 1.609344L;long double operator"" _km(const long double val){ return val;}long double operato..
vcpkg는 Microsoft 및 C++ 커뮤니티에서 유지 및 관리하는 무료 오픈 소스 C/C++ 패키지 관리자이다. 2016년에 시작된 이 기능은 개발자가 프로젝트를 최신 버전으로 마이그레이션하는 데 도움을 준다. vcpkg는 Windows, MacOS, Linux에서 개발자가 사용하는 플랫폼 간 도구로 발전했다. vcpkg에는 모든 빌드 및 프로젝트 시스템을 지원하여 개발 프로세스를 용이하게 하도록 설계된 오픈 소스 라이브러리 및 엔터프라이즈 지원 기능의 대규모 레지스트리가 있다. vcpkg는 핵심 C++ 도구이며 CMake의 스크립트를 사용하여 C++로 작성된다. C/C++ 개발자 환경의 고유한 문제를 해결하기 위해 처음부터 설계되었다.vcpkg를 사용해야 하는 이유2,200개가 넘는 오픈 소스 라..
// string1.h #pragma once #include using std::ostream; using std::istream; class String { public: // 생성자와 기타 메서드 String(const char* s); // 생성자 String(); // 디폴트 생성자 String(const String& st); // 복사 생성자 ~String(); // 소멸자 int length() const { return len; } // 오버로딩 연산자 메서드 String& operator=(const String& st); String& operator=(const char* s); char& operator[](const int i); const char& operator[](cons..
함수 포인터는 표기법이 난해하다는 문제를 가지고 있다. const double* f1(const double arr[], int n); const double* f2(const double [], int); const double* f3(const double*, int); // 함수 포인터 배열 const double* (*pa[3]) (const double*, int) = {f1, f2, f3}; pa는 리턴형이 const double*이고, 매개변수로 const double*와 int형을 받을 수 있는 함수 포인터 3개를 저장할 수 있는 함수 포인터 배열이다. pa를 가리키는 포인터를 만드려면 어떻게 해야 할까? 명확하게, 선언은 pa를 선언하는 것과 유사하지만, *가 더 필요하다. 새로운 포인터..
재귀 호출은 하나의 작업을 서로 비슷한 두 개의 작은 작업으로 반복적으로 분할해가면서 처리해야 하는 상황에서 특별히 유용하다. 예를 들면, 눈금자를 그리는 데 이것을 적용할 수 있다. 두 개의 끝을 먼저 표시한 후 그들의 중간 지점을 찾아 눈금을 표시한다. 동일한 절차를 눈금자의 왼쪽 절반에 대해 수행한다. 그리고 나서 눈금자의 오른쪽 절반에 대해서도 같은 절차를 수행한다. 눈금 간격을 더욱 세분하려면 현재의 눈금 구획에 대해 동일한 절채를 다시 수행한다. 이러한 재귀적인 접근을 "분할 정복(divide-and-conquer)" 전략이라고 한다. #include using namespace std; const int LEN = 66; const int DIVS = 6; void subdivide(char..
cin.get(char)를 이용한 입력 일반적으로 문자 단위로 입력을 읽어들이는 프로그램들은 빈칸 문자, 탭 문자, 개행 문자까지 포함하여 모든 문자를 읽어들여야 한다. cin이 속해 있는 istream 클래스는 이런 요구를 만족시키는 멤버 함수들을 가지고 있다. 특별히 cin.get(ch) 멤버 함수는 빈칸 문자까지도 입력받아 ch 변수에 저장한다. #pragma warning(disable: 4996) #include using namespace std; int main() { char ch; int count = 0; cin.get(ch); while (ch != '#') { cout
vector 템플릿 클래스 vector 템플릿 클래스는 동적 배열에 속하는 string 클래스와 유사하다. 프로그램에 실행되는 동안 vector 객체의 크기를 세팅할 수 있고, 새로운 데이터를 마지막에 추가하거나 중간에 데이터를 삽입할 수도 있다. 기본적으로 동적 배열을 생성하기 위해 new를 사용하는 것을 대체할 수 있다. 실제로 vector 클래스는 메모리를 관리하기 위해서 new와 delete를 사용하지만, 그 과정은 자동으로 진행된다. 몇 가지 기본적이고 실질적인 문제를 살펴보도록 하자. 첫째, vector 객체를 사용하기 위해서는 vector 헤더 파일을 포함해야 한다. 둘째, vector 식별자는 std 이름 공간의 일부분이기 때문에 using 명령, using 선언 또는 std::vector..
때로는 프로그램이 1바이트로 표현할 수 없는 문자 세트(예를 들면 일본어, 중국어, 한국어 문자 세트)를 처리해야 하는 경우도 있다. C++는 이것을 두 가지 방법으로 처리한다. 첫째, 확장 문자 세트가 시스템의 기본 문자 세트이면, 컴파일러 개발업체가 char형을 처음부터 2바이트(16비트) 또는 그 이상으로 만드는 것이다. 둘째, 기본 문자 세트와 확장 문자 세트를 동시에 지원하는 것이다. 즉, 보통의 8비트 char형으로 기본 문자 세트를 나타내고, wchar_t형(wide character type에서 w, char, t를 각각 따 왔다)으로 확장 문자 세트를 나타내는 것이다. wchar_t형은 시스템에서 사용되는 가장 큰 확장 문자 세트를 나타낼 수 있을 만큼의 충분한 비트 폭을 가진 정수형이다..
// 예를 들어 int타입의 최대 값을 구하고 싶다면 헤더 파일을 포함시킨 후 // numeric_limits::max() 처럼 호출하면 된다. #include #include #include using namespace std; template void ShowRange(const char* typeName) { cout
STL은 이름 그대로 템플릿을 사용해서 만들어진 라이브러리다. STL은 일반적으로 많이 사용하는 클래스와 함수들이 만들어져 있는데, 예를 들어 링크드 리스트 클래스, 동적 배열 클래스, 정렬 함수, 검색 함수 등과 같이 범용적인 클래스와 함수들이 있다. 또한 이런 클래스와 함수들은 템플릿으로 만들어져 있기 때문에 확장이 용이하다. STL은 사용함으로써 얻을 수 있는 장점들이 있다. 첫번째, STL은 표준이다. 이는 지구 반대편에 있는 개발자도 나와 똑같은 클래스와 함수를 사용한다는 것을 의미한다. 때문에 상대방이 작성해놓은 코드를 쉽게 알아볼 수 있다. 두번째, STL은 전문가들이 만들어 놓은 것이기 때문에 직접 만든 것보다 효율적이고 안전하다. 물론 엄청난 실력자라 STL에 있는 것보다 훌륭하게 만들 ..
C++의 코딩 표준에 대해 알아보자. https://docs.popekim.com/ko/coding-standards/cpp C++ 코딩 표준 | 포프의 문서창고 제대로 대우받는 개발자 | 부족한 컴공지식 배우기 | MIT급 컴공인강 최저임금으로 고통받는 일회성 프로그래머는 그만! POCU 아카데미가 올해 연봉협상을 책임지겠습니다! docs.popekim.com
템플릿은 C++에서 없어서는 안될 아주 중요한 기능인데 템플릿을 사용하면 컴파일러가 개발자를 대신해서 클래스나 함수를 만들어내게 할 수 있다. 그리고 C++에는 이러한 템플릿을 사용해서 만들어진 다양한 클래스와 함수들을 STL이라는 이름으로 제공하고 있다. 왜 템플릿을 사용해야 할까? 템플릿은 C++에서 가장 눈에 띄는 기능이라고 할 수 있다. C++의 다른 기능들은 Java와 C# 같은 객체지향 언어에서도 대부분 지원하는 것들이지만 템플릿 만큼은 C++이 아니면 찾아볼 수 없는 독특한 기능이기 때문이다. 템플릿은 함수를 자동으로 생성하는 것에 더해서 클래스까지 자동으로 생성해줄 수 있다. 그리고 이 두 가지를 구분하기 위해서 템플릿 클래스, 템플릿 함수 등으로 나누어 부르게 된다. 템플릿 클래스 #in..
C++ 개발자가 선호하는 11가지 라이브러리를 소개한다. 1. 액티브 템플릿 라이브러리 (Active Template Library, ATL) 액티브 템플릿 라이브러리(Active Template Library, ATL)는 COM(구성 요소 개체 모델) 개체를 만들 수 있는 템플릿 기반 C++ 클래스의 세트이다. https://learn.microsoft.com/ko-kr/cpp/atl/active-template-library-atl-concepts?view=msvc-170 ATL(액티브 템플릿 라이브러리) 개념 자세한 정보: ATL(활성 템플릿 라이브러리) 개념 learn.microsoft.com 2. 아시오 C++ 라이브러리 (Asio) asio는 네트워크 프로그래밍을 위한 C++ 라이브러리다. 오..
프로젝트의 크기가 커지게 되면 소스 파일의 수도 많아지고, 또 소스 파일들 안에서 정의도니 수많은 변수, 함수, 구조체, 클래스, 열거체 등이 존재하게 된다. 이런 경우에는 관련된 코드별로 그룹을 나누어서 관리하면매우 효율적인데 이때 네임스페이스(namespace)가 관련된 코드를 나누어 담을 수 있는 논리적인 가방의 역할을 한다. 왜 네임 스페이스를 사용해야 할까? 실세 현장에서 개발하는 프로젝트는 수백 개 이상의 소스 파일로 이루어져 있다. 그리고 이 파일들 안에는 수천, 수만 개의 이름이 존재한다. 변수, 함수, 클래스, 구조체, 열거체, 타입 재정의(typedef)를 사용할 때마다 새로운 이름이 생겨나는 것이므로 충분히 수만 개에 달할 수 있다. 중요한 것은 이렇게 정의한 이름들이 모두 한 공간에..
형 변환을 할 때는 괄호를 사용했다. 이 방법은 C언어에서 사용하던 방식이다. C++에서는 이를 대체할 수 있는 4가지 종류의 형변환 연산자가 추가되었다. 이 연산자들을 살펴보자. C++ 스타일의 형 변환을 사용해야 하는 이유? 한 마디로 말해 C 스타일의 형변환은 두 가지 문제점이 있다. C 스타일의 형 변환은 눈에 잘 띄지도 않고 툴을 사용해서 찾아내기도 힘들다. 왜냐하면 형변환 말고도 괄호를 사용하는 부분이 많기 때문이다. C++ 스타일의 형 변환은 눈에 잘 띄는 외관을 가지고 있기 때문에 형변환을 수행하는 코드를 한눈에 알아 볼 수 있다. 그렇다면 눈에 잘 띄지 않는 것이 왜 단점이 될까? 그것은 명시적인 형 변환은 언제나 문제의 소지가 있기 때문이다. 명시적인 형변환을 수행한다는 것은 암묵적인 ..
구조적 예외 처리는 예외 상황을 효율적으로 처리할 수 있게 도와주지만 잘못 사용하는 경우에는 화를 입을 수도 있다. 구조적 예외 처리에는 어떤 문제점이 존재하고 또 어떻게 해결해야 하는지 알아보자. 리소스를 정리하기 전 예외가 발생한 경우의 문제점 구조적 예외 처리에서 가장 빈번하게 일어나는 문제는 리소스를 정리하기 전에 함수가 종료되는 경우다. 다음의 예제는 예외로 인해서 할당된 메모리가 해제되지 못하는 문제점을 가지고 있다. #pragma warning(disable: 4996) #include using namespace std; void A(); void B(); int main(void) { try { A(); } catch (const char* ex) { cout
예외 처리가 프로와 아마추어를 구분하는 기준이 될 수 있다는 점을 기억하자. 반환 값을 사용한 예외 처리 다음의 예제를 살펴보자. // DynamicArray.h #pragma once class DynamicArray { public: DynamicArray(int arraySize); ~DynamicArray(); bool SetAt(int intdex, int value); int GetAt(int index) const; int GetSize() const; protected: int* arr; int size; }; // DynamicArray.cpp #include "DynamicArray.h" DynamicArray::DynamicArray(int arraySize) { arr = new i..
순수 가상 함수 부모 클래스의 멤버 함수를 자식 클래스에서 재정의하는 것을 오버라이딩(overriding)이라고 부른다. 이 개념은 오버로딩과 혼동하지 않게 주의해야 한다. 오버라이딩과 관련한 몇 가지 주제를 살펴보는데, 먼저 순수 가상 함수를 살펴보자. 순수 가상 함수(Pure Virtual Functions)는 가상 함수의 한 종류다. 순수 가상 함수는 왜 사용할까? 순수 가상 함수를 만드는 방법은 간단하다. 가산 함수의 선언 뒤에 다음과 같이 '=0'을 붙여주면 된다. 마치 함수에 0값을 대입한 것처럼 보인다. virtual void Draw() const = 0; 순수 가상 함수는 함수의 정의 부분이 필요하지 않다. 위와 같이 함수의 원형망 가지고 있는 함수가 바로 순수 가상 함수다. 그렇다면 하..
언제 가상 함수가 필요할까? 가상 함수의 필요성을 알아보려면 소스 코드를 보는 것이 가장 좋다. 다음의 예제를 보자. #include using namespace std; class Shape{ public: void Move(double x, double y); void Draw() const; Shape(); Shape(double x, double y); protected: double _x, _y; }; Shape::Shape(): _x(0), _y(0) {} Shape::Shape(double x, double y): _x(x), _y(y) {} void Shape::Move(double x, double y){ _x = x; _y = y; } void Shape::Draw() const{ cout