프로젝트공부아이디어
    • 2월
    • 1월
  • 30

    26. 1. 30.

  • 29

    26. 1. 29.

  • Day9

    26. 1. 27.

  • Day8

    26. 1. 26.

  • Day5

    26. 1. 23.

  • Day1

    26. 1. 22.

  • Day2

    26. 1. 22.

  • Day3

    26. 1. 22.

  • Day4

    26. 1. 22.

로딩 중...

30

2026. 1. 30.

constexpr vs const

const는 런타임에 확정되는 상수 constexpr은 컴파일 타임에 확정되는 상수 https://modoocode.com/293

C++
int main(){	int a;	const int b = a; // a는 컴파일 타임에 알 수 없지만 어쨌든 b는 상수임	constexpr int b = a;  // a가 컴파일 타임에 정해지지 않으면 에러 발생}
  • constexpr로 함수와 객체도 선언할 수 있다
C++
#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

람다

  • 무명함수지만 사실은 객체
C++
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 };... -----------------------------------------------------------------
  • 람다 캡쳐 문법
C++
#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로 사용할 수 있게 된다.
C++
#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 파일을 링킹하기 때문에 헤더만 있으면 중복으로 인지함

  1. cpp 파일을 직접 쓰기
  2. static 붙여주기
  3. inline 붙여주기(컴파일러에 따라 함수 여러번 스택에 쌓는 코드면 inline처리 안해줄 수도)

인라인 함수

  • 자꾸 헷갈리는데 인라인 함수는 컴파일 타임에 함수 호출부가 함수 내부 코드로 치환되는 함수임
  • 함수 호출 오버헤드 패널티(CPU가 다른 레지스터와 함께 실행 중인 현재 명령어의 주소를 저장해야하므로 모든 함수 매개변수를 생성해야함) 최적화 기법.
  • 내부 루프가 없는 짧은 함수에 인라인을 붙이면 성능이 향상된다
  • 하지만 권장사항일 뿐, 컴파일러는 인라인 요청을 때에 따라(복잡한 함수일 때) 무시할 수 있다
  • 더욱이 현대 컴파일러는 인라인 요청이 없더라도 성능 향상이 보장된다면 자동으로 함수를 인라인화한다.

엔진 렌더러

vertex buffer(어느 색상에) index buffer(어느 위치에) shader(어떤 이미지를) -> 렌더러는 이것만 알면 됨. 액터가 submit 멀티쓰레드..스레드 타이밍..cpu는 잘게 쪼개서..gpu는 최대한 한 번에

C++
// 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;}
왼쪽 화살표2902오른쪽 화살표