📘

필요한것만골라배우는 모던 C++

C++ 기초부터 시작하는 책
어느정도 프로그래밍에 익숙한 사람을 대상으로 하는 책
메모리 심화 과정 존재
번역의 다양성, 또는 이중성을 완화하기 위해서 번역가가 각주를 상세하게 달아주어서 좋다!

0. 프롤로그

C++ 시작하기 전에

1.
CMake 라는 빌드 자동화 툴의 기본 사용을 알아야 한다.
2.
컴파일러 종류에 대해서는 자세히 몰라도 되나, 어떠한 종류로 컴파일 할지는 정해야 한다

CMake Tutorial

1. CMakeLists.txt 파일 생성

1.
프로젝트 root 에 CMakeLists.txt 파일 생성
2.
cmake_minimum_required(VERSION) - 선언, 빌드툴 cmake 버전을 명시한다
# 설치되어있는 cmake 버전 확인 cmake --version
Bash
복사
4.
add_executable(EXE_NM, FILE_PATH) - 실행명, 실행파일위치 지정
실행파일위치는 CMakeLists.txt 기준으로 상대 주소로 적을수 있다.
5.
set(CPP_VERSION) CPP 버전 기입하기
6.
add library

2. CMakeLists.txt 샘플

cmake_minimum_required(VERSION 3.27.8) project(modern_cpp VERSION 0.0.1) set(CMAKE_CXX_STANDARD 20) add_executable(prologue sample/main.cpp)
Plain Text
복사
24.02.24

1. C++ 기초

Hello world

#include<iostream> using namespace std; int main() { cout <<. "Hello world!" << endl; return 0; }
C++
복사

Intrinsic type

내장타입 - 별다른 #include 없이 사용가능한 c++ 기본형식
CPU 아키텍쳐 (32비트, 64비트) 등에 따라 바이트수가 달라질수 있다.
UE5 에서는, UE5 기본 변수를 사용하는 것이 좋다!! int32, int64 등은 특정 아키텍쳐에 종속되지 않고 언제나 같은 사이즈(용량)의 메모리를 할당한다
세로 - 기본타입
가로 - 접두사
unsigned
long
char
unsigned char
long char
short
unsigned short
long short
long
unsigned long
long long
float
unsigned float
long float
double
unsigned double
long double
bool
X (없음)
X (없음)

char, string

기본 문자의 배열은 c 의 배열과 같다. → 반드시 마지막 문자는 /0 (null) 이 되어야 한다.
// 문자 5개 + 공백문자(/0) = 6개 char Name[6] = "Hello";
C++
복사
std::string 사용하기
동적 문자열
각종 편의 기능 (문자열 더하기 등) 현대 문자열 문법 모두 사용 가능
#include<string> int main() { std::string Name = "Hello"; }
C++
복사

Declare variables

변수는 최대한 사용되기 직전에 할당한다
auto → 타입 추론
// C++11 // 기본적으로 1은 int 형이 된다 auto number = 1; int other = 2; auto result = number + other;
C++
복사
const 상수화 → 처음 선언뒤 값이 바뀌지 않는 상수
const int id = 1;
C++
복사

Literal

값에 접미사를 붙혀(보통은 숫자) 내장타입을 지정할 수 있다.
literal
intrinsic type
2
int
2u
unsigned int
2l
long
2ul
unsigned long
2.0
double
2.0f
float
2.0l
long double
값에 접두사를 붙혀 n진법을 나타낼수 있다
literal
0x
16 진수
0
8 진법
0b (C++14)
2 진법
1,000 단위 seperator 입력가능 (C++14)
long d = 1'000'000;
C++
복사
문자열 접미사 s (C++14)
짧은 문자열 (16바이트) 는 자동으로 char 배열로 작동한다.
string 클래스로 초기화 하는것을 강제한다면 접미사 s 를 붙혀주어야 한다.
std::string str = "Hello world!"s;
C++
복사
Braced initialization
초기화시, 선언한 변수의 크기보다 더 큰 값을 입력할 때, 에러를 내줌
long l = {213123213213};
C++
복사

Scope

기존에 알고 있던 개념과 동일

Operator

! 대신에 not 연산자를 쓸수 있다
= 에 대한 바른 정의
A = B 라면, A 의값에 B 를 복사하여 입력한다
, 콤마 → 1줄에 여러 연산을 쓸수 있게 해주나, 제일 마지막 연산만 왼값으로 배정가능
마지막 이전의 산술은 실행은 되지만 배정은 되지 않는다
// a = 8 int a = 3 + 4, 7 + 1;
C++
복사

Control statement

if 문에서 조거부 변수선언 가능한 문법이 추가 C++17
→ GO 의 if 문과 형식이 같다
if (auto res = d.is_good(); !res) { cout << "not fine" << endl; }
C++
복사
foreach
int primes[] = {2, 3, 4, 5}; for (int i : primes) { std::cout << i << endl; }
C++
복사

Function

구성요소
Argument
→ caller 입장에서 정리하면 쉽다
call by value
call by reference
→ 상수포인터 전달
값을 포인터로 전달하나, 포인터의 주소값은 변경 불가능하게 전달하는 방법
double tow_norm(const vector& v) { ... }
C++
복사
→ default argument
double root(double x, int degree = 2) { ... }
C++
복사
Return type
inline 화 → 컴파일러가 필요시 자동으로 복사, 붙혀넣기 하여, 함수 호출이 아닌, 코드의 복사 형태의 프로그램으로 자동으로 만들어 준다
inline double square(double x) { return x * x; }
C++
복사
Function name
function overloading
함수명과 리턴타입이 같으나 Argument 가 다른 함수 모음, 항수(=arity) (Argument 의 갯수)
Argument 는 자동형변환( int → long ) 등이 일어나므로, 주의 해야 한다

Main function

Main 문은 다은 3종류가 있다
int main() {} int main(int argc, char* argv[]) {} int main(int argc, char** argv) {}
C++
복사

Error handling

에러 처리에는 다음 2방식이 대표적이다
1.
Assertion → 값 평가 후 프로그램 종료, 또는 진행
2.
Exceiption → 값 평가 후, 부모로 회귀 또는 진행
assert
→ a 가 0 보다 크지 않으면 프로그램이 바로 종료된다
#include<cassert> // c 에서 발전된 assert 함수 모음 int main() { int a = 3; assert(a > 0); return 0; }
C++
복사
→ assert 함수는 #define NDEBUG 매크로를 통해서 스킵할수 있으므로 디버깅 후 삭제하지 않아도 된다
→ 코드에서 선언하지 않아도, 컴파일러 옵션에서 -DNDEBUG 추가하면 assert 코드는 스킵된다
→ static_assert : 컴파일시 확인, 자세한 내용은 추후 다룰 예정
except
→ try - catch, throw 를 통한 보편적 방식
→ function 선언시 noexcept 로 선언하면, 에러가 없음을 명시 할 수 있다
double square_root(double x) noexcept { ... }
C++
복사

Input output stream

#include<iostream>
자세한것은 사용할 때 쯤, 다시 보도록 한다

Array, Pointer, Reference

Array - 배열
→ 컴파일시 크기가 정해져야한다. 동적배열은 다른방식으로 관리
→ 사용후 메모리 해제 필수 delete[] a;
// 3.0f 에서 에러남 int a[] = {1, 2, 3.0f}; delete[] a;
C++
복사
Pointer
→ 생성하면 힙 + 스택에 동시에 메모리 할당
→ 삭제 할때는 delete 명령어로 해제 해주어야 한다
int* ip = new int; delete ip; // null 포인터로 초기화 int* null_ptr1 = nullptr; int* null_ptr2 {};
C++
복사
Smart pointer
C++11 - unique_ptr, shared_ptr, weak_ptr ( #include<memory> )
1.
unique_ptr
a.
유일포인터 → 서로 다른 포인터가 같은 데이터를 가르킬 일이 없다
b.
주소값 중복제거를 시스템상 보장
c.
scope 를 벗어나면 메모리는 자동해제 된다
d.
주소값으 복사는 불가능하나, 이동은 가능하다
e.
원시 포인터와 거의 비슷한 성능을 가진다
unique_ptr<double> dp1 {0.1f}; unique_ptr<double> dp2; dp2 = std::move(dp1);
C++
복사
2.
shared_ptr
a.
다수의 포인터가 한가지 데이터를 바라보게 하는 포인터
b.
더 이상, 공유하는 포인터가 없을 때 자연소멸한다
c.
new 대신에 make_shared 함수로 생성한다
shared_ptr<double> p1 = make_shared<double>(); auto p2 = make_shared<double>();
C++
복사
3.
weak_ptr
a.
순환참조방지
Reference
참조 → 포인터이나, 반드시 값을 참조해야하고 수정불가능
Container
Array → Vector
p.96 - 24.02.24