C++ 53

[언리얼 엔진5][기초 2장] 충돌 감지

개요 언리얼 엔진에서 콜리전속성을 가진 컴포넌트끼리는 충돌이 일어날 수 있다. 여기서 각 콜리전 설정에 따라 해당 콜리전은 각 채널의 콜리전들에 대해서 block되거나 overlap되거나 ignore될 수 있다. block은 서로 막히며 충돌 이벤트가 발생한다. overlap은 막히진않지만 겹침 이벤트가 발생한다. ignore은 무시다. 두 콜리전이 충돌하면 서로가 상대 채널에 대해 처리되는 설정 중 더 낮은 처리가 일어난다. ex)block block => block block overlap => overlap overlap ignore => ignore 충돌 이벤트 엑터 엑터의 notifyHit멤버 함수를 오버라이드하면 엑터가 가진 컴포넌트의 콜리전이 충돌 시 해당 정보들과 함께 해당 함수가 호출된다..

[언리얼 엔진5][기초 1장] 엑터와 컴포넌트

엑터와 컴포넌트 언리얼 엔진은 월드안에 엑터들이 존재하며 엑터들은 컴포넌트들을 가지고 있다. 여기서 엑터는 오로지 월드위에만 존재 할 수 있으며 다른 엑터에 속할 수 없다.(월드 상의 트랜스폼 배치를 이야기하는 것 이다. 클래스에서 다른 엑터의 참조를 가지는 등은 당연히 가능) 대신 엑터가 가지는 컴포넌트들이 엑터 아래에서 계층적으로 존재한다. 엑터 바로 아래에 루트 컴포넌트가 존재하며 그 아래 계층적으로 존재한다. 엑터 ㄴ 루트 컴포넌트 ㄴ컴포넌트 ㄴ컴포넌트 ㄴ컴포넌트 ㄴ컴포넌트 그럼 계층적인 트랜스폼은 어떻게 표현할까? 컴포넌트 중 씬 컴포넌트는 트랜스폼을 가지는 컴포넌트이다. 이러한 컴포넌트들의 계층으로 계층적인 트랜스 폼을 표현 가능하다. 여기서 루트 컴포넌트는 반드시 씬 컴포넌트나 그의 자손(C..

[Effective C++]항목 23~25 : 클래스에 대한 비멤버 함수

항목 23 : 비멤버 비프렌드로 제공가능한 함수는 그렇게 만들자 public 함수 a,b,c를 가지고 있는 클래스 widget이 있다고 하자. 이때 클래스에 d라는 함수를 추가한다고 하자. d는 자체적인 private접근없이 a,b,c를 차례로 호출하는 기능만을 가지는 함수이다. 즉 유틸함수에 가까운 함수이다. 이때 d라는 함수를 멤버 함수로 만들 수도 있겠지만 그보단 외부에서 호출하는 비멤버 비프렌드 util함수로 선언하는 것이 좋다. d(widget& w)로 위젯을 받아 위젯의 a,b,c를 순서대로 호출하면 된다. 마치 절차지향처럼 말이다. 모순적이게도 이러한 함수 구현 방식이 클래스의 캡슐화를 향상 시킨다. 이게 무슨 소리일까? 역할군이 확실히 나누어진 객체지향 작업에서 클래스 제작자가 클래스의 내..

[Effective C++]항목 18~22 : 클래스 설계 기초

항목 18 : 실수가 일어날 수 없는 인터페이스를 제공하자. 매개변수 실수 방지 일,월,년을 매개변수로 받는 멤버 함수를 만든다고하자. 세가지 매개변수가 모두 int라면 사용자가 어느나라 사람이느냐에 따라서 일월년의 순서가 헷갈릴 수 있다. 따라서 일,월,년에 해당하는 클래스를 각각 만들고 이를 매개변수로 받는 등으로 하여 헷갈리는 상황을 방지할 수 있다.자원 해제 실수 방지동적할당한 자원을 포인터만 그대로 돌려주는 함수는 좋지 못하다. 사용자에게 할당해제 책임을 맡기게 되기 때문이다. 이를 막기 위해선 스마트 포인터등에 담아서 리턴해주는 것이 좋다. 추가로 단순 할당해제가 아닌 추가적인 자원 해제가 필요하다면 스마트 포인터의 삭제자를 활용하면 된다. 스마트 포인터의 추가적인 이점은 자원의 할당과 해제가..

[Effective C++]항목 13~17 : 자원 관리

항목 13 : 자원 관리는 객체로 하자 동적 할당된 메모나, 뮤텍스 잠그기등의 여러 자원들은 할당을 받은 뒤 사용을 끝내고 반드시 해제를 해야한다. 이러한 기능을 우리가 사용하거나 남이 사용하도록 인터페이스를 만들어줄 때는 사용자가 직접 반납을 하도록 하는 것이 아니라 이 자원을 관리하는 객체를 두고 그 객체의 소멸자가 자원을 해제하도록 하는 것이 좋다.대표적인 예시가 스마트 포인터이다. unique_ptr이나 shared_ptr등으로 동적할당된 메모리 또는 포인터를 관리하자. 만약 자신이 동적할당으로 만든 자원의 포인터를 리턴해주는 함수를 만들었다면 로우 포인터가 아닌 스마트포인터에 담아 리턴해주자.이러한 초기화시 자원을 획득하고(받거나 생성) 소멸 시 자원을 해제하는 기법을 RAII라 하며 이러한 객..

[Effective C++]항목 9~12 : 생성자, 소멸자 및 대입 연산자 2

항목 9 : 객체 생성 및 소멸 과정에서는 자신의 가상 함수를 호출하면 위험하다.객체 생성 시점에서는 조상 클래스의 생성자부터 호출되어 아래로 내려간다. 한 후손 클래스가 생성된다고 하자. 그러면 최상위 조상의 생성자부터 호출하며 내려갈것이다. 이때 중간의 한 조상이 생성자에서 자신의 가상함수를 호출하면 그 생성이 후손 클래스의 생성과정임에도 불구하고 호출한 자기자신의 실제 함수가 호출되어 버린다. 이는 아직 조상 자신까지의 생성만 진행되고 후손 부분의 생성은 아직 진행되지않아 현재 생성 시점에서는 실제 타입이 조상 자신의 타입으로 인식되기 때문이다. 만약 이것이 노린 것이라면 모르겠지만 보통 가상함수는 실제 타입의 함수를 호출하려는 목적이 대부분이므로 이를 생각하며 사용하는 것이라면 피해야한다. 소멸자..

[Effective C++]항목 5~8 : 생성자, 소멸자 및 대입 연산자 1

항목 5 : 클래스에서 자동으로 생성되는 메소드들 C++에서는 우리가 따로 작성하지 않으면 컴파일러가 자동으로 생성하는 기본 메소드들이 있다. 기본 생성자 각 멤버의 기본 생성자 호출 생성자가 없을 시 자동으로 생성 복사 생성자 각 멤버 간 복사 생성자 호출복사 생성자, 이동 생성자, 대입 연산자 중 하나라도 있을 시 생성안됨 복사 대입 연산자 각 멤버 간 복사 대입 연산자 호출 복사 대입 연산자, 이동 생성자, 대입 연산자 중 하나라도 있을 시 생성안됨 이동 생성자 각 멤버 간 이동 생성자 호출 이동 생성자, 복사 생성자, 복사 대입 연산자, 이동 대입 연산자, 소멸자 중 하나라도 있을 시 생성안됨 이동 대입 연산자 각 멤버 간 이동 대입 연산자 호출 이동 대입 연산자, 복사 생성자, 복사 대입 연산자..

[Effective C++]항목 1~4 : C++ 기초 사고방식

항목 1 : C++은 언어들의 연합체이다. C++은 다중패러다임 프로그래밍 언어로써 절차,객체 지향 프로그래밍, 함수형 프로그래밍, 일반화 프로그래밍등의 다양한 프로그래밍 패러다임을 적용할 수 있다. 이러한 C++을 공부할땐 다소 혼란스러울 수 있는데 이러한 C++을 다음 네가지 영역으로 구분한다면 도움이 될 수 있다. C : 기존 C에서도 제공되던 부분들이며 C의 규칙들을 따른다. 객체 지향 개념의 C++: C++로 넘어오며 추가된 클래스등의 객체지향 개념들이다. 템플릿 C++ : C++의 강력한 기능중 하나인 템플릿을 활용하는 부분들이다. 일반화에 큰 힘을 준다. STL : 표준 라이브러리로 컨테이너와 알고리즘, 반복자와 함수 객체들로써 돌아간다. C++을 구성하고 있는 이 네가지 부분에 대한 패러다..

[게임 서버][7장]데이터베이스

개요 데이터베이스는 기본 파일시스템위에서 b트리, 해쉬테이블등으로 효율적인 데이터 관리와 동시에 여러 질의, 원자성 등의 추가적인 기능들을 사용할 수 있게 만들어진 데이터 관리 시스템을 말한다. 이때 DBMS이라는 프로그램으로 데이터베이스 만들고 관리 할 수 있다. DBMS는 사용자가 DBMS의 인터페이스로 데이터베이스를 생성하면 파일 시스템위에 자신의 자료구조와 알고리즘을 이용하여 자신의 데이터베이스 파일을 구축하고 기능들을 제공해준다. 이러한 기능들을 파일 시스템 위에 직접 구현하여 사용할 수도 있겠지만 인력과 시간이 상당히 많이 들어가기에 대부분의 경우 상용 DBMS를 이용하여 데이터베이스를 사용한다. 보통 게임 뿐 아니라 대부분의 분야에서 서버에 데이터베이스를 사용할때는 DBMS로 운용되는 데이터..

[게임 서버][6장]프라우드넷

개요 프라우드넷은 게임 서버, 클라이언트 프레임워크인 네트워크 엔진 중 하나이다. 한국의 Nettention에서 개발하였으며 현재는 펄어비스의 자회사가 되었다. ​ 기본 구조 프라우드넷은 서버와 클라이언트 프로그램 각각에서 NetServer 클래스와 NetClient 클래스를 각자 사용한다. 서버에서는 NetServer.Create()로 NetServer인스턴스를 생성 한뒤 NetServer.Start()로 서버를 열 수 있다. 특정 프로토콜 버전(우리가 만들고 있는 프로그램의 프로토콜 버전으로 스스로의 버전 동기화에 사용하면 된다.)과 리스닝 포트를 넣으면서 Start를 호출하면 해당 포트에 서버가 열린다. 클라이언트에서는 CNetClient.Create()로 인스턴스를 생성하고 CNetClient.C..