용어
용어 | 번역, Full Name | 의미 |
Assertion | 어설션 | 프로그램의 일부분에서 예상되는 조건이 참이라고 가정하고, 해당 조건이 실제로 참인지 확인하는 방식으로 작성되는 프로그래밍 검사 기법 중 하나 |
SEH | Structured Exception Handling |
예외처리
- 예외처리는 에러에 대응하기 위한 코딩기법
- 오류가 발생한 시점에서 실행을 중단, 방어코드를 실행하고 마무리
MSVS - 설명서 : https://learn.microsoft.com/ko-kr/cpp/cpp/exception-handling-in-visual-cpp?view=msvc-170
C 스타일의 주요 버그 클래스는 메모리 누수입니다.
획득된 자원의 초기화(RAII;Resource Acquisition Is Initialization)원칙은 리소스의 획득과 해제를 자동으로
처리하겠다는 것을 목표로 합니다.
이는 디자인 패턴, 즉 개발자가 직접 리소스를 획득/해제 해야하는 책임이 있음을 의미합니다.
Java의 Garbage Collection 메모리 관리기법은 java머신(JVM)이 더 이상 사용되지 않는 객체를 자동으로 탐지하고 해제합니다.
따라서, 개발자가 직접 개입하지 않습니다.
예외처리 루틴에서 메모리 관련 예제가 많은 것은 그것이 주요이슈이기 때문이지 전부가 아닙니다. java를 포함한 대부분의 언어가 예외처리 루틴을 가지고 있습니다.
try { ... 오류 발생에 대비할 코드 ... ... throw "오류 메시지"; } catch(데이터타입 오류파라미터) { ... 오류 발생시 처리할 코드 }
stack unwinding
stack unwinding(스텍풀기)는 메모리 해제(관리)등 에러관리에 의해 발생할 수 있는 수행에 관한 처리를 의미합니다.
try {
... 1
... 2 오류 발생함
... 3 수행되지 않음
} catch(데이터타입 오류파라미터) {
... 오류 발생시 처리할 코드
}
class A { ~A() {} 오류 수정 이전에 수행 } try { A a ... 1 ... 2 오류 발생함 ... 3 수행되지 않음 } catch(데이터타입 오류파라미터) { ... 오류 발생시 처리할 코드 }
다중 오류처리
에러메시지의 데이터타입에 따라서 어떤 catch문을 수행할지 결정합니다. 여러 종류의 에러를 처리할 때, 가장 구체적인(자식) 에러부터, 보편적인(부모) 에러를 배치해야하며, 가장 마지막에 모든에러(...)가 배치됩니다.
try { ... throw 에러메시지 } catch(데이터타입1 e) { ... } catch(데이터타입2 e) { ... } catch(데이터타입3 e) { ... } catch(...) { ... 처리되지 못한 모든 에러 처리 }
에러메시지의 데이터타입에 따라서 어떤 catch문을 수행할지 결정합니다.
class A; class B : public A; try { ... } catch(B e) { ... } catch(A e) { ... }
Except Object
#include <exception>을 통해 C++ 표준 예외 클래스들을 사용 할 수 있습니다.
오류 클래스 | 설명 |
domain_error | 연산의 결과가 유효한 범위 이내인지 판단하는 오류 |
length_error | 문자열, 배열, 파일크기 등에서 참조할 수 있는 길이 제약에 위배되는 오류 |
logic_error | (잘못된 조건if, 반복, 참조값 오류로 인한) 논리적인 오류 |
overflow_error | 변수의 연산이 표현 범위를 넘어선 경우(오버플로우) |
range_error | 특정 시스템이 허용하는 범위를 벗어낫을 때, 입력이 1 ~ 5라든가 |
runtime_error | 런타임에 발생하는 일반적인 오류를 나타내는 예외 |
underflow_error | 언더플로우(unsigned에서, 2 - 3)가 발생한 경우를 나타내는 예외 |
noexcept
어떤 함수 내에서 예외가 발생하지 않는다고 명시하려면, noexcept예약어를 사용합니다. 해당 함수에서 throw가 발생하면 비정상 종료가 됩니다.
scope
class나 struct에 속한 멤버 함수/변수를 ::연산자(scope resolution operator)를 이용해 선택할 수 있습니다.
class A { int foo; };
A::foo = 10;// Class에 속한 멤버를 선택합니다.
using
namespace로 여러개의 객체와 함수를 하나의 단위로 묶을 수 있습니다.
namespace myName {
void foo();
class bar;
}
myName::foo(); // Namespace에 속한 객체를 선택합니다.
myName::bar;
재정의 할 수 있습니다.
using U8 = char;
동적 할당
프로그램 수행 중, 상황에 따라 메모리 요청을 해야 할 때, 힙(heap)영역에 할당됩니다.
영영이름 | 설명 |
Stack | 함수 호출, 지역정보, 매개변수, 복귀주소 정보가 후입선출(LIFO)방식으로 저장 |
Heap | 동적할당된 메모리를 저장 |
Data | Static변수영역, 지정된 초기값으로 시작, 종료까지 할당 유지 |
Code(text) | 기계코드 저장 |
BBS | Block Started by Symbol, 초기화되지 않은 static, 프로그램 시작시 0으로 초기화 |
char* p = new char[len + 1];
cast
캐스트 연산자 | 설명 |
---|---|
const_cast | const 한정자를 추가하거나 제거하는데 사용됩니다. |
static_cast | 다른 타입으로의 명시적인 변환에 사용됩니다. |
dynamic_cast | 상속 계층 구조에서의 다운캐스팅과 가상 함수를 통한 업캐스팅에 사용됩니다. |
reinterpret_cast | 다른 포인터 타입 간의 재해석, 포인터와 정수 간의 변환 등에 사용됩니다. |
int i; const int* p = &i; int* q = const_cast<int*> (p);
int i = 5; cout << static_cast<float>(i) / 3
class A; class B : A; A* pa; B* pb; pb = static_cast(pa); // downcast pa = static_cast(pb); // upcast(Error)
int intValue = 10; double doubleValue; doubleValue = reinterpret_cast(intValue);
C++ types
C++98부터 도입되었습니다. bool, wchar_t, char16_t, char32_t, auto 등의 타입을 사용할 수 있습니다.
데이터 타입 | 크기 (바이트) |
---|---|
bool | 1 |
wchar_t | 2 (일반적으로) |
char16_t | 2 |
char32_t | 4 |
nullptr
- C++11부터 도입
- nullptr 의 값은 0, 의미는 포인터
- 타입 안정성: 정수타입으로 암시적으로 변하지 않음
- 함수 오버로딩 호환: 인자값이 Null, '0'일 때, 정수/포인터 오버로딩 함수의 구분가능
void foo(int a); // 1 void foo(int* a); // 2 foo(0); // 1 호출 foo(nullptr); // 2 호출
C++연산자
C++98부터 아래 연산자가 추가되었습니다.
키워드 | 설명 |
---|---|
and_eq | 비트 단위 AND 연산 후 대입 연산을 수행합니다. |
or_eq | 비트 단위 OR 연산 후 대입 연산을 수행합니다. |
xor_eq | 비트 단위 XOR 연산 후 대입 연산을 수행합니다. |
not_eq | 같지 않음을 비교하는 데 사용되는 비교 연산자입니다. |
bitand | 비트 단위 AND 연산을 수행합니다. |
bitor | 비트 단위 OR 연산을 수행합니다. |
true | 참(진실)을 나타내는 불리언 값입니다. |
false | 거짓을 나타내는 불리언 값입니다. |
and | 논리 AND 연산을 수행합니다. |
or | 논리 OR 연산을 수행합니다. |
xor | 논리 XOR(배타적 OR) 연산을 수행합니다. |
not | 논리 NOT 연산을 수행합니다. |