본문 바로가기

Script/C++10

[C++] Chapter 10. 콜백 함수 (Callback) 콜백함수 함수 포인터 + 함수 객체 + 템플릿 콜백 (Callback) : 다시 호출하다? 역으로 호출하다? 게임을 만들 때, 이런 콜백의 개념이 자주 등장한다. ex) MoveTask 실습 등 어떤 상황이 일어나면 → 이 기능을 호출해줘 ex) UI 스킬 버튼을 누르면 → 스킬을 쓰는 함수를 호출 (함수 포인터 or 함수 객체 등 으로 넘겨줌) 함수 포인터는 사용 안했고, 함수 객체와 템플릿을 사용한 예 class Item { public: int _itemId = 0; int _rarity = 0; int _ownerId = 0; } class FindByOwnerId { public: // 함수 객체를 사용하기 위한 연산자 오버로딩 bool operator()(const Item* item) { r.. 2023. 5. 15.
[C++] Chapter 09. 템플릿(Template) #2 템플릿 : 함수나 클래스를 찍어내는 툴 함수 템플릿 클래스 템플릿 클래스 템플릿 사용 전 class RandomBox { public: int GetRandomData() { int idx = rand() % 10; return _data[idx]; } public: int _data[10] } int main() { srand(time(nullptr)); RandomBox rb1; for (int i = 0; i < 10; ++i) { rb1.data[i] = i; } int value1 = rb1.GetRandomData(); cout 2023. 5. 12.
[C++] Chapter 08. 템플릿(Template) #1 템플릿 : 함수나 클래스를 찍어내는 툴 함수 템플릿 클래스 템플릿 함수 템플릿 사용 전 void Print(int a) { cout 2023. 5. 12.
[C++] Chapter 07. 함수 객체 함수 객체 (Functor) : 함수처럼 동작하는 객체 함수 포인터의 단점 완전히 동일한 시그니처로 만들어진 함수만 들고있을 수 있지만, 함수 객체를 사용하면 어느 정도 극복 가능 시그니처가 안 맞으면 사용할 수 없다. 상태를 가질 수 없다. (멤버를 가질 수 없어서 경우에 따라서 기존에 실행했던 또는 저장했던 데이터를 유지시키고 싶지만 그럴 수 없다.) [함수처럼 동작]하는 객체 그래서 () 연산자 오버로딩이 필요하다 class Functor { public: void operator()() { cout 2023. 5. 12.
[C++] Chapter 06. 함수 포인터 포인터라는 건 주소를 담는 바구니. int add(int a, int b) { return a + b; } int sub(int a, int b) { return a - b; } int main() { int a = 10; typedef int DATA; // 1) 포인터 * // 2) 변수이름 pointer // 3) 데이터 타입 int DATA* pointer = &a; // 함수 (고전적인 방식) typedef int(FUNC_TYPE)(int, int); // mordern C++ using FUNC_TYPE = int(int a, int b); // 1) 포인터 * // 2) 변수이름 fn // 3) 데이터 타입 함수 (인자는 int, int. 반환은 int) FUNC_TYPE* fn; // 함.. 2023. 5. 12.
[C++] Chapter 05. 크러쉬가 나는 오작동 현상 case by case 정수가 오버플로우 0을 나누기 재귀함수를 호출해서 스택 오버플로우 소멸자에 virtual을 쓰지 않아 memory leak이 일어났다 nullptr로 밀어주지 않아 double-free 이미 삭제된 애를 다시 사용하는 use-after-free 2023. 5. 12.
[C++] Chapter 04. 객체지향 여행 객체지향의 시작 💡 절차(procedural)지향 프로그래밍 procedure = 함수 어떤 절차를 지켜야된다의 절차라기 보다는 함수기반이 메인이되는 프로그래밍 방식 C++도 객체지향 프로그래밍이냐? 애매하다 C++에서 C에서 파생되어서 여러 문법들이 추가되면서 생겼다보니까 엄밀히 말해 혼혈화 같은 느낌이다. // 데이터 + 가공(로직, 동작) // 객체지향 = 객체 // 객체란? 플레이어, 몬스터 GameRoom 생성자와 소멸자 // 클래스에 ‘소속’된 함수들을 멤버 함수라고 함 // 이 중에서 굉장히 특별한 함수 2종이 있는데, 바로 [시작]과 [끝]을 알리는 함수들 // - 시작(탄생) -> 생성자 (여러 개 존재 가능) // - 끝(소멸) -> 소멸자 (오직 1개만) 소멸자는 main 함수가 끝난.. 2023. 5. 12.
[C++] Chapter 03. 포인터#2 (포인터 vs 배열) 배열 기초 배열의 크기는 상수여야함. (VC 컴파일러 기준. 다른 컴파일러는 상수값이 아니여도 통과될 수 있음) 배열의 이름은 배열의 데이터가 아니라 배열의 시작주소이다. (첫번째 시작주소) 정확히는 시작 위치를 가리키는 TYPE* 포인터이다. 포인터 vs 배열 const char* test1 = “Hello World”; char test2[] = “Hello World”; 둘이 비슷하게 설정된다는 점에서 포인터와 배열이 똑같아보인다고 하지만 이는 전혀 다르다. (둘이 어셈블리 코드도 다름) test1 = “Hellow World”; .data 주소[H][e][l][l][o][][W][o][r][l][d][\0] readonly 데이터임 test1[ 주소 ] char*) 즉 배열의 내용 전체를 넘긴게 .. 2023. 5. 11.
[C++] Chapter 02. 포인터#1 (기초, Reference) 포인터 기초 #1 포인터를 사용하기 전 사용한 방식 int number = 1; number라는 이름의 4바이트 정수 타입의 바구니를 만든다. number라는 변수 스택 메모리에 할당 number = 1라 함은, number 바구니에 1이라는 숫자를 넣으라는 의미. 따라서 스택 메모리에 있는 특정 주소(number 바구니)에 우리가 원하는 값을 넣은 셈 number는 비유하자면 메모리에 이름을 붙인 것 (찰떡같이 알아들어서) 나쁘지 않고 편리한데, 단점은 원본 수정이 불편하다. 포인터는 바구니는 바구니인데.. [주소를 저장하는 바구니]다. 참고) 포인터는 개발환경이 64비트 32비트냐에 따라 8바이트 4바이트 고정 크기로 설정된다. int value 1 = *ptr 이걸 디스어셈블리로 보면 💡 00344.. 2023. 5. 11.
[C++] Chapter 01. 함수 스택 프레임 int result = MultiPlayBy(b, a) 라고 한다면, 어셈블리 언어로 까보면 오른쪽부터 a를 먼저 push해준다. 지역 변수와 값 전달 데이터 영역에 .rodata, .data, bbs 세가지 영역이 있었음. 초기화 여부, const 등 세부사항에 따라 각 영역에 할당됨 호출스택에서 스택프레임이 구성되는 건 [매개변수][RET][지역변수] 사실 스택이란거 자체는 처음부터 충분히 큰 공간을 할당을 해놓고 시작을 한다. 거기서 각기 함수들이 원하는 영역만큼을 찝어가지고 사용한다. [매개변수][RET] 세팅은 이전 함수에서 정해서 넘겨주게 된다. 지역변수는 온전히 자기 자신이 제어한다. void IncreaseHP(int hp) { int finalHP = hp + 1; } // .. 2023. 5. 11.