30
constexpr vs const
const는 런타임에 확정되는 상수 constexpr은 컴파일 타임에 확정되는 상수 https://modoocode.com/293
int main(){ int a; const int b = a; // a는 컴파일 타임에 알 수 없지만 어쨌든 b는 상수임 constexpr int b = a; // a가 컴파일 타임에 정해지지 않으면 에러 발생}constexpr로 함수와 객체도 선언할 수 있다
#include <iostream>constexpr int Factorial(int n) { int total = 1; for (int i = 1; i <= n; i++) { total *= i; } return total;}template <int N>struct A { int operator()() { return N; }};int main() { A<Factorial(10)> a; // A<3628800> a로 계산됨 std::cout << a() << std::endl;}constexpr생성 제약조건- 리터럴 타입이어야 함
- 초기화(instantiate)되어야 함
- 실행 중간에
constexpr가 아닌 함수를 호출해선 안됨
constexpr함수는 컴파일 타임 상수가 아닌 값들도 받을 수 있음. 그럴 땐 일반 함수처럼 동작함
Literal type
람다
- 무명함수지만 사실은 객체
int main() { std::vector<int> moneyVector; moneyVector.emplace_back(100); moneyVector.emplace_back(4000); moneyVector.emplace_back(50); moneyVector.emplace_back(200); int totalMoney = 0; std::for_each( moneyVector.begin(), moneyVector.end(), [&totalMoney](int money) { totalMoney += money; } ); std::cout << "Total Money : " << totalMoney << std::endl; std::cin.get(); return 0; }----------------------------------------------------------------- 위의 람다 코드를 C++가 개념적으로 생성하는 람다 코드..(설명을 위한 예시) ... struct __Lambda_42 { int& totalMoney; // 참조 캡처. void operator()(int money) { totalMoney += money; } }; __Lambda_42 f { totalMoney };... ------------------------------------------------------------------ 람다 캡쳐 문법
#include <iostream>int main(){ int number1, number2, number3, number4, number5; [&, number1, number2]{}; // number3, number4, number5는 참조, number1, number2는 복사 [=, &number1, &number2]{};// number3, number4, number5는 복사, number1, number2는 참조 [number1, number1]{}; // Error. 같은 변수를 캡처함. [&, &number1]{} // Error. number1을 이미 default 참조로 사용함. [=, number1]{} // Error. number1을 이미 default 복사로 사용함. std::cin.get();}- ㅈㄴ 드럽네
smart pointer
- 언리얼엔 가비지 컬렉터가 있다. 그래서 new 연산자로 동적할당을 직접 하면 안된다. 대신 해주는 키워드가 있다
- stack = 자동메모리, heap = 자유 메모리
unique_ptr
- 특정 변수의 포인터 소유권을 단일로 유지한다. 새 소유자로 상속시켜줄 순 있지만 다른 변수로 복사하거나 공유할 순 없다
- - 제일 가볍고 효율적이다

shared_ptr
- 원시 포인터 하나를 여러 변수에서 공유할 때 쓰는 포인터.
- 모든 shared_ptr 소유자의 소유권이 해제되어야 힙 영역에서 삭제시킨다
-

weak_ptr
- shared_ptr의 변형, shared_ptr의 포인터에 접근할 수 있지만 참조 횟수에 포함되진 않는다
- 실제 힙 영역에 참조하는 메모리가 살아있는지 확인할 수 있는 함수를 제공한다(안전함)
- shared_ptr의 순환참조 문제를 해결하기 위한 기법
- 클래스의 참조 변수를 weak_ptr로 지정해주면 shared_ptr을 해당 멤버 변수에 지정했을 때 shared_ptr이 아닌 weak_ptr로 사용할 수 있게 된다.
#include <iostream>#include <memory>class Resource{public: Resource() { std::cout << "자원 획득!\n"; } ~Resource() { std::cout << "자원 해제\n"; } void Use() { std::cout << "자원 사용\n"; } void SetOther(std::weak_ptr<Resource> other) { this->other = other; std::shared_ptr<Resource> otherResource = other.lock(); if (otherResource) { otherResource->Use(); } else { std::cout << "객체가 이미 소멸됨.\n"; } }private: std::weak_ptr<Resource> other;};int main(){ std::shared_ptr<Resource> resource1 = std::make_shared<Resource>(); std::shared_ptr<Resource> resource2 = std::make_shared<Resource>(); resource1->SetOther(resource2); resource2->SetOther(resource1);}예시
중앙에 리소스 매니저가 있다. 텍스쳐와 모델링이 있다. 하나의 플레이어 오브젝트에서 모델링과 텍스쳐를 써야할 때
- 중앙 리소스 매니저의 텍스쳐와 모델링 변수에는 shared_ptr 지정이 필요하다.
- 플레이어 오브젝트에선 일반적으로 weak_ptr 지정을 통해 안전하게 사용한다.
수학 벡터
헤더에 명세 선언
헤더에 선언과 구현을 같이하면 링커 오류가 발생할 수 있음 일반함수를 헤더에 구현해놓으면 링커는 cpp 파일을 링킹하기 때문에 헤더만 있으면 중복으로 인지함
- cpp 파일을 직접 쓰기
- static 붙여주기
- inline 붙여주기(컴파일러에 따라 함수 여러번 스택에 쌓는 코드면 inline처리 안해줄 수도)
인라인 함수
- 자꾸 헷갈리는데 인라인 함수는 컴파일 타임에 함수 호출부가 함수 내부 코드로 치환되는 함수임
- 함수 호출 오버헤드 패널티(CPU가 다른 레지스터와 함께 실행 중인 현재 명령어의 주소를 저장해야하므로 모든 함수 매개변수를 생성해야함) 최적화 기법.
- 내부 루프가 없는 짧은 함수에 인라인을 붙이면 성능이 향상된다
- 하지만 권장사항일 뿐, 컴파일러는 인라인 요청을 때에 따라(복잡한 함수일 때) 무시할 수 있다
- 더욱이 현대 컴파일러는 인라인 요청이 없더라도 성능 향상이 보장된다면 자동으로 함수를 인라인화한다.
엔진 렌더러
vertex buffer(어느 색상에) index buffer(어느 위치에) shader(어떤 이미지를) -> 렌더러는 이것만 알면 됨. 액터가 submit 멀티쓰레드..스레드 타이밍..cpu는 잘게 쪼개서..gpu는 최대한 한 번에
// pseudo codenamespace Wanted{ struct RenderCommand { // 그리는데 필요한 데이터 Vector2 position; Color color = Color::White; char image = ' '; }; // DLL 내부에서만 사용하므로 WANTED_API 사용 안함 class Renderer { public: // 그리기, Draw call은 렌더러만 호출하도록 static void Draw(const char image) { for (const ) { Draw(); } std::cout << image; } };private: static std::vector<RenderCommand> commands;}