🛠 C, C++ 11

friend

외부의 클래스나 함수가 해당 클래스에 public으로 접근할 수 있도록 강제하는 키워드.편리하지만 캡슐화를 위반하는 위험한 키워드이다. 난발하지 않도록 하자.// 외부의 함수void Func(int x);// 외부의 클래스class Foo{ ... };class Bar{ friend void Func(int); // 특정 함수에 대한 friend화 friend class Foo; // 특정 클래스 전체에 대한 friend화 friend void Foo::Func(); // 특정 클래스의 특정 메서드에 대한 friend화 // 이제 friend로 지정된 범위에선 Bar의 모든 멤버가 public인 것처럼 접근할 수 있다.}; friend를 붙이고 그 자리에서 바로 함수나 클래스를 정의..

🛠 C, C++/문법 2025.04.27

constexpr

정의객체 혹은 함수의 리턴값을 컴파일 타임에 알 수 있는 상수식으로 만드는 키워드.컴파일러가 컴파일 타임에 어떤 식의 값을 결정할 수 있다면, 해당 식을 상수식(Constant expression)이라고 한다. 특히 정수 상수식은 쓰임이 굉장히 많다.int arr[size]; // 배열의 크기 size는 상수식이어야 한다.template struct A { ... };A a; // 템플릿은 컴파일 타임에 생성되므로 템플릿 인자 number는 상수식이어야 한다.enum Fruit { Apple = number, Grape, Berry }; // enum 값 number는 상수식이어야 한다.쓰임constexpr 키워드가 붙은 변수는 그 자체로 상수식이 된다. 따라서 담기는 값은 컴파일 타임에 결정될 수 있..

🛠 C, C++/문법 2025.04.27

concept, requires

C++20에서 추가된 템플릿 메타 프로그래밍을 위한 도구.requires 키워드로 올 수 있는 템플릿 타입의 조건을 규정하고(어떤 타입이 올 수 있는지 정의할 뿐 아니라, 매개변수에 의미론적(semantic) 제약을 가할 수도 있다), concept로 이를 캡슐화할 수 있다. concept캡슐화된 제약 조건 덩어리.컴파일 타임에 결정되는 bool을 반환하거나 그러한 값으로 귀결될 수 있어야 한다.constexpr, consteval 키워드로 bool 타입을 반환하는 컴파일 타임 함수를 만들어 사용할 수도 있고, , 헤더에 정의된 제네릭 함수들을 써도 된다.형식 제약 컨셉템플릿 타입이 '어떤 타입'이어야 한다는 형식 제약을 규정한다.concept 이름 = 형식 제약 꼴로 선언하며, 컴파일 타임에 boo..

🛠 C, C++/문법 2025.04.27

포인터와 배열

C++에선 훨씬 쉽고 편리하며 직관적인 가변 길이 배열 STL 컨테이너를 사용하도록 하자. 배열과 포인터C/C++에서 배열은 특정한 크기의 할당된 메모리 블록을 의미한다. 이 때 배열명은 특별한 의미를 가진다.일반적으로 배열명 arr은 &arr[0] 즉 배열의 첫 번째 요소의 주소를 가리키는 포인터로 암시적 변환된다.단, 아래의 상황에선 예외로 배열 전체를 의미한다.sizeof(arr) 은 배열의 전체 크기를 반환한다.&arr 은 '배열 전체의 시작 주소'를 의미한다. 따라서 &arr + 1은 '배열 전체의 다음 번지'를 가리킨다.이 차이 때문에 다소 헷갈리는 문법이 된다. 다음은 배열명에 대한 주소 연산이 가지는 의미이다.// int arr[4];arr -> 첫 번째 요소의 주소 (&arr[0])&ar..

🛠 C, C++/문법 2025.04.27

가상 함수 (Virtual function)

OOP의 핵심인 다형성, 그 중에서도 가장 중요하다고 할 수 있는 서브타입 다형성(런타임 다형성, 오버라이딩)을 구현하기 위한 개념. C++에선 부모 클래스의 함수 서명을 자식 클래스에서 그대로 사용할 경우, 부모 클래스의 함수는 숨겨지게 된다. 예컨대 Foo() 라는 함수가 부모와 자식 모두에 존재하면, 자식 객체를 통해 Foo()를 호출하면 자식의 Foo()가 호출되게 된다. 물론 그렇다고 부모의 Foo() 함수가 사라진 것은 아니다. 부모의 타입을 명시하여 접근하는 것으로 호출은 가능하다. (물론, 호출되는 위치에서 접근이 가능하다면) 문제는 부모 타입 포인터가 기본적으로 부모 타입의 함수에만 접근할 수 있다는 데에 있다. 다형성을 활용하려면 부모 타입 포인터가 업캐스팅된 자식 타입 객체를 가리키게..

🛠 C, C++/문법 2025.04.20

(작성중) Module

불편한 C/C++의 컴파일 방식을 개선하기 위해 도입된 시스템. C++20부터 추가되었다. 사용법C++ Language Standard 설정 C++20 이상으로 설정Enable Experimental C++ Standard Library Module Yes로 설정Tools -> Get Tools and Features -> 개별 구성 요소 -> v143 빌드 도구용 C++ 모듈 설치되어있나 확인. 기본지식VS에서 모듈 파일의 확장자는 ixx(Module Interface Unit) (근데 다른 확장자 써도 됨)모듈의 접근자는 :: 대신 .을 쓴다. (ex: std.core) 표준 모듈std.core → 아래에 있는 것들을 제외한 대부분의 표준 라이브러리std.regex → std.filesystem → ..

assert, static_assert

Assertion이란?특정 지점에서 특정 조건이 참일 것을 가정하고, 참이 아니라면 프로그램의 실행을 중단하고 에러를 출력하는 기능. C에서는 #error 전처리자나 헤더에 정의된 assert 매크로를 사용해 Assertion이 가능했다.// #error 전처리자. 전처리 단계에서 #error를 만나면 컴파일 오류를 발생시킨다. 이 때, 뒤에 나오는 errortoken-string 문자열을 출력한다.#ifndef ENGINE#error Engine is not included.#endif// assert 매크로. 런타임에 표현식을 체크하여 false일 경우 런타임 에러를 발생시킨다.#include void foo(int age){ assert(age > 0); // 표현식이 참이 아닐 경우 에러 ..

🛠 C, C++/문법 2025.03.23

원자성 연산, atomic

원자성 연산이란?더이상 쪼개질 수 없는 연산. 다른 스레드가 끼어들기 전에 '전부 처리하거나' 또는 '아무것도 하지 못 하는' 두 가지 상태만이 존재할 수 있는 연산을 말한다.즉 별도의 조치 없이도 경쟁 상태나 메모리 가시성 문제가 발생하지 않는 연산.메모리 가시성 문제메모리 값의 갱신은 한 틱만에 발생하지 않으며 일반적으로 중간다리를 거쳐 이루어진다. 예컨대 스레드A가 메모리 0x01 주소의 값에 11을 기록하려고 '일련의 입력 프로세스'에 진입했는데, 그 밑에서 생성된 스레드B는 아직 입력 프로세스가 끝나지 않아 새 값이 기록되기 전의 메모리를 읽어들일 수 있다.비슷한 문제로 코드 재배치 문제도 있다. 컴파일러는 딱히 멀티스레드 환경을 고려해 로우 레벨 코드를 생성하지 않기 때문에 그게 더 효율적이라..

[스레드] 2. <thread> 라이브러리 (thread, mutex, condition_variable, future)

std::threadC++11에서 추가된 새로운 스레드 표준. OS마다 알아서 다른 함수를 호출해 스레드를 생성한다.기존의 WinAPI 스레드 함수를 사용하는 것보다 훨씬 편리하다.다음과 같이 사용한다.std::thread t1(진입함수); // 스레드 객체가 생성되는 동시에 새 스레드를 생성한다.// std::thread t; // 혹은 빈 스레드 객체만 만들어놓고// t = std::thread(진입함수); // 나중에 생성해도 된다.// 스레드가 콜백(흐름이 종료되고 호출자에게 반환)될 때까지 대기한다.t.join();// 스레드를 백그라운드에서 돌아가게 만들고 반환여부를 신경쓰지 않는다.t.detach(); 스레드 객체는 생성과 동시에 동작에 필요한 자원(진입점 정보, 스레드의 스택프레임, 스레드..

[스레드] 1. WinAPI, CRT 스레드 함수

윈도우즈 스레드 생성 함수C 시절의 WinAPI 함수인 CreateThread() 함수는 CRT와 연동이 되지 않아 다음과 같은 문제가 있었다.스레드를 생성할 때 CRT가 필요한 초기화를 수행하지 않아 로컬 저장소에 접근할 때 문제가 발생할 수 있다.스레드가 종료될 때 CRT가 스레드 생성에 필요한 메모리 찌꺼기를 자동으로 해제하지 못 한다.따라서 CreateThread() 함수를 래핑한 CRT의 _beginthreadex() 함수가 만들어졌다.두 함수 모두 윈도우즈에서 스레드를 생성하는 함수임에 주의하자.물론 C++11에서 추가되어 표준이 된 라이브러리는 OS에 따라 다른 함수를 호출한다. 작동 원리1. 스레드 생성_beginthreadex()에 진입점 함수의 주소와 함께 전달할 void* 매개변수를..