728x90
반응형

C++ 161

[C++] Catching Exception

void f() { try { throw E{}; } catch(H) { // when do we get here? } } 핸들러는 호출된다. H가 E와 같은 유형인 경우 H가 E의 명확한 공개 기반인 경우 H와 E가 포인터 유형이고 [1] 또는 [2]가 참조하는 유형에 대해 유지되는 경우 H가 참조이고 [1] 또는 [2]가 H가 참조하는 유형에 대해 유지되는 경우 또한 예외를 잡는 데 사용되는 유형에 const를 추가할 수 있다. 이것은 우리가 잡을 수 있는 예외 집합을 변경하지 않는다. catch 된 예외를 수정하지 못하도록 제한할 뿐이다. 참조로 예외를 catch 할 가능성에 유의하자. 예외 유형은 종종 그들이 나타내는 오류 종류 간의 관계를 반영하기 위해 클래스 계층의 일부로 정의된다. 예외 클래..

[C++] throwing exception

복사하거나 이동할 수 있는 모든 유형의 예외를 throw 할 수 있다. class No_copy { No_copy(const No_copy&) = delete; // prohibit copying (§17.6.4) }; class My_error { // ... }; void f(int n) { switch (n) { case 0: throw My_error{}; // OK case 1: throw No_copy{}; // error : can’t copy a No_copy case 2: throw My_error; // error : My_error is a type, rather than an object } } catch 된 exception object는 원칙적으로 throw 된 객체의 복사본이다..

[C++] Finally

소멸자를 사용하여 리소스를 클래스의 객체로 표현하는데 필요한 규율은 일부를 귀찮게 한다. 계속해서 사람들은 예외가 발생한 후 정리할 임의의 코드를 작성하기 위해 finally를 만들었다. 이러한 기술은 애드혹(adhoc)이기 때문에 일반적으로 RAII보다 좋지 않지만 원한다면 RAII는 애드혹을 제공할 수 있다. 먼저 소멸자에서 임의의 작업을 실행할 클래스를 정의한다. template struct Final_action { Final_action(F f): clean{f} {} ˜Final_action() { clean(); } F clean; }; finally action은 생성자에 대한 인수로 제공된다. 다음으로, 액션의 유형을 편리하게 추론할 수 있는 함수를 정의한다. template Final_..

[C++] 리소스 관리

함수가 리소스를 획득할 때(즉, 파일을 열고, 여유 저장소에서 일부 메모리를 할당하고, 뮤텍스를 획득하는 등) 리소스가 적절하게 해제되는 시스템의 향후 실행을 위해 종종 필수적이다. 종종 적절한 릴리즈는 호출자에게 반환하기 전에 이를 획득한 함수가 릴리스하도록 할 수 있다. void use_file(const char∗ fn) // naive code { FILE∗ f = fopen(fn,"r"); // ... use f ... fclose(f); } fopen() 호출 후 및 fclose() 호출 전에 문제가 발생하면 예외로 인해 fclose()가 호출되지 않고 use_file()이 종료될 수 있다는 것을 알아차릴 때까지는 그럴듯해 보인다. 예외 처리를 지원하지 않는 언어에서도 똑같은 문제가 발생할 수..

[C++] 미리 정의된 매크로

몇 가지 매크로는 컴파일러에서 미리 정의한다. __cplusplus. C++컴파일에 정의되어 있다.(C컴파일에는 없음) __DATE__. "yyyy:mm:dd" 형식의 날짜 __TIME__. "hh:mm:ss"형식의 시간 __FILE__. 현재 소스 파일의 이름 __LINE__. 현재 소스 파일 내의 소스 라인 번호 __FUNC__. 현재 함수의 이름을 지정하는 구현 정의 구현 정의된 C-스타일 문자열 __STDC_HOSTED__. 구현이 호스팅 되는 경우 1 그렇지 않으면 0. 또한 구현 시 몇 가지 매크로가 조건부로 정의됨 __STDC__. C 컴파일에서 정의됨(C++ 컴파일에서는 없음) __STDC_MB_MIGHT_NEQ_WC__. wchar_t에 대한 인코딩에서 기본 문자 집합의 구성원이 일반 문..

[C++] constexpr 함수

일반적으로 함수는 compile-time에서 평가할 수 없으므로 상수 표현식에서 호출할 수 없다. constexpr함수를 지정함으로써 상수 표현식이 인수로 주어지면 상수 표현식에서 사용할 수 있기를 원한다는 것을 나타낸다. constexpr int fac(int n) { return (n>1) ? n∗fac(n−1) : 1; } constexpr int f9 = fac(9); // must be evaluated at compile time constexpr이 함수 정의에서 사용될 때, "상수 표현식이 인수로 주어지면 상수 표현식을 사용할 수 있어야 한다"라는 의미다. 객체 정의에서 사용하면, compile-time에 intiailizer를 평가한다는 의미다. void f(int n) { int f5 =..

[C++] 함수의 지정자와 수정자

이름, 인수 집합 및 반환 유형을 지정하는 것 외에도 함수 선언에는 다양한 지정자와 수정자가 포함될 수 있다. 함수의 이름 (필수) 인수 목록, 없을 경우 ()로 표시 (필수) 반환 유형은 void 일 수 있고 접두사 접미사 일 수 있다 (필수) inline. 함수 본문을 인라인 하여 함수 호출을 구현 constexpr. 상수 표현식이 인수로 주어지면 compile-time에 함수를 평가할 수 있어야 함을 나타냄 noexcept. 함수가 예외를 throw하지 않을 수 있음 [[noreturn]]. 일반 호출/반환 메커니즘을 사용하여 함수가 반환되지 않음. 또한 멤버 함수는 다음과 같이 지정할 수 있다. virtual. 파생 클래스에서 재정의할 수 있음 override. 기본 클래스의 가상 기능을 재정의해..

[C++] 명시적 유형 변환

때때로 한 유형의 값을 다른 유형의 값으로 변환해야 한다. 이러한 변환은 언어 규칙에 따라 암시적으로 수행된다. double d = 1234567890; // integer to floating-point int i = d; // floating-point to integer 다른 경우에는 명시적이어야 한다. 논리적이고 역사적인 이유로 C++는 다양한 편의성과 안전성을 가진 명시적 유형 변환 작업을 제공한다. {} 표기법을 사용하여 새 값의 유형 안전 구성을 제공하는 구성 다양한 수준의 변환을 제공하는 명명된 변환 - const로 선언된 항목에 대한 쓰기 액세스 권한을 얻기 위한 const_cast - 잘 정의된 암시적 변환을 되돌리기 위한 static_cast - 비트 패턴의 의미를 변경하기 위한 re..

[C++] lambda expression

람다 함수 또는 람다라고도 하는 람다식은 익명 함수 객체를 정의하고 사용하기 위한 단순화된 표기법이다. operator()로 명명된 클래스를 정의하는 대신 나중에 해당 클래스의 객체를 만들고 마지막으로 호출하는 대신 약식을 사용할 수 있다. 이것은 연산을 알고리즘에 인수로 전달하려는 경우에 특히 유용하다. GUI(및 다른 곳)의 context에서 이러한 작업을 종종 callback이라고도 한다. 이 섹션에서는 람다의 기출적 측면에 중점을 둔다. 람다 사용에 대한 예제와 기술은 다른 곳에서 찾을 수 있다. 람다 표현식은 일련의 부분으로 구성된다. 람다 식의 본문에 사용할 수 있는 정의 환경의 이름과 참조 복사 또는 액세스 할지 여부를 지정하는 비어 있을 수 있는 capture 목록. capture 목록은 ..

[C++] Constant Expressions

C++에서 'constant'는 두 가지 관련 의미를 제공한다. constexpr : 컴파일 타임에 평가 const : scope 내 수정 방지 기본적으로 constexpr의 역할은 compile-time 평가를 활성화하고 보장하는 반면 const의 주요 역할은 인터페이스에서 불변성을 지정하는 것이다. 여기서는 compile-time 평가와 관련 있다. 컴파일 시 알려지지 않은 값은 사용할 수 없으며 이에 대한 side effect는 없다. 궁극적으로 constant 표현식은 정수, 실수, 열거자로 시작해야 하며 다음을 수행하는 constexpr 함수와 연산자를 사용하여 이들을 결합하여 값을 생성할 수 있다. 또한 일부 주소는 일부 형태의 상수 표현식에서 사용할 수 있다. (따로 논의) 누군가가 리터럴이..

[C++] 계산기 만들기 (5) the driver

The Driver 프로그램의 모든 부분이 제자리에 있다면 드라이버만 추가하면 작업을 시작할 수 있다. 실제 계산을 수행하는 calculate()와 실제 수행을 하게 되는 main() 함수로 구성된다. Token_stream ts {cin}; // use input from cin void calculate() { for (;;) { ts.get(); if (ts.current().kind == Kind::end) break; if (ts.current().kind == Kind::print) continue; cout get(ch) && isalnum(ch)) ct.string_value += ch; ip->putback(ch); ct.kind = Kind::name; return ct; } error..

[C++] 계산기 만들기 (3) low-level input

Low-level input 지금까지 정의된 대로 계산기를 사용하면 몇 가지 불편한 점이 드러난다. 값을 출력하기 위해 표현식 뒤에 세미콜론을 추가하는 것은 지루한 면이 있고 이름이 공백만으로 끝나는 것은 골치 아픈 일이다. 예를 들어, x=7은 식별자 x 뒤에 연산자 = 와 숫자 7이 오는 것이 아니라 식별자 - 다. 원하는 것을 얻으려면 x =7 뒤에 공백을 추가해야 한다. 두 문제 모두 get()의 type-oriented default input을 읽는 코드로 교체하여 해결할 수 있다. Token Token_stream::get() { char ch; do { // skip whitespace except ’\n’ if (!ip−>get(ch)) return ct={Kind::end}; } whi..

[C++] 계산기 만들기 (2) input

Input 입력 읽기는 종종 프로그램에서 가장 곤란한 부분이다. 사람과 의사소통하기 위해 프로그램은 그 사람의 변덕, 관습 및 겉으로 보기에 무작위적인 오류에 대처해야 한다. 사람이 기계에 더 적합한 방식으로 강요하는 것은 공격적으로 간주되기도 한다. 저수준 입력 루틴의 작업은 문자를 읽고 문자에서 더 높은 수준의 토큰을 구성하는 것이다. 이런 토큰은 상위 수준 루틴에 대한 입력 단위다. 여기서 저수준 입력은 ts.get()에 의해 수행된다. 저수준 입력 루틴을 작성하는 것이 일상적인 작업일 필요는 없다. 많은 시스템은 이를 위한 표준 기능을 제공한다. 먼저 Token_stream의 전체 정의를 확인해 보자. class Token_stream { public: Token_stream(istream& s)..

[C++] 계산기 만들기 (1) parser

부동 소수점 숫자에 대한 중위 연산자로 네 가지 표준 산술 연산을 제공하는 간단한 탁상용 계산기 프로그램을 만들어보자. 사용자는 변수를 정의할 수도 있다. 예를 들어 주어진 입력 r = 2.5 area = pi ∗ r ∗ r (pi는 미리 정의됨) 계산기 프로그램은 다음과 같은 결과를 보여 줍니다. 2.5 19.635 여기서 2.5는 첫 번째 입력 라인의 결과이고 19.635는 두 번째 라인의 결과다. 이 계산기는 네 개의 메인 파트로 구성된다. (parser, 입력 함수, 기호 테이블, driver). 실제로 이것은 구문 분석기가 구문 분석을 수행하고 입력 기능이 입력 및 어휘 분석을 처리하며 기호 테이블이 영구 정보를 보유하고 driver가 초기화, 출력 및 오류를 처리하는 소형 컴파일러다. 더 유용..

[C++] range-for 문

가장 간단한 루프는 range-for 명령문이다. 단순히 범위의 각 요소에 대한 프로그래머 액세스 권한을 제공한다. int sum(vector& v) { int s = 0; for (int x : v) s+=x; return s; } for(int x : v)는 "범위 v의 각 요소 x에 대해" 또는 "v에 있는 각 x에 대해"로 읽을 수 있다. v의 요소는 처음부터 마지막까지 순서대로 동작된다. 요소(여기서는 x)를 명명하는 변수의 범위는 for문이다. 콜론 뒤의 표현식은 시퀀스(범위)를 나타내야 한다. 즉, 반복자를 얻기 위해 v.begin() 및 v.end() 또는 begin(v) 및 end(v)를 호출할 수 있는 값을 생성해야 한다. 컴파일러는 먼저 begin 및 end 멤버를 찾고 이를 사용하려..

728x90
반응형