C++ Type deduction

C++ 에서의 형식 연역
Effective Modern C++ Chapter 1.


Type deduction in template

1
2
3
4
template <typename T>
void f(ParamType param);

f(expr);

위 코드는 컴파일 단계에서 expr로 부터 TParamType에 대한 형식 연역이 이루어진다. 이때 T의 형식 연역은 exprParamType에 영향을 받는다.



ParamType이 l-value ref 인 경우

Read more

this adjustment

MSVC 컴파일러에서 상속시 발생할 수 있는 this 포인터 문제


Callback 인터페이스를 제공하는 클래스를 디자인하던 중 발생한 this 포인터 문제에 대해서 정리하기 위해서 작성하였음. 빌드 환경은 윈도우 + MSVC컴파일러.

this 포인터의 잘못된 참조

목표는 몇 가지 콜백함수를 등록하고, 특정 상황에 맞게 호출할 수 있는 인터페이스를 제공하는 클래스를 디자인하는 것이다. 여러 방법 중 해당 클래스를 상속하여 인터페이스를 이용하는 방식을 선택하였다.

먼저 상속관계에서 콜백을 호출하는 간단한 테스트를 진행하였고, 그 과정에서 문제를 발견하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class ICallback
{
protected:
typedef void(ICallback::* Callback)();

void CallProc(Callback proc)
{
(this->*proc)();
}
};

class Test : public SomeClasses, public ICallback
{
int data{ 10 };
public:
void RegisterFoo()
{
CallProc((Callback)&Test::foo);
}

void foo()
{
printf("%d\n", this->data);
}
};

int main()
{
Test* t = new Test;
t->RegisterFoo();
}
Read more

Event handling

이벤트를 처리하는 방법에 대하여


프로그램 런타임에 Event가 발생하면 EventManager는 이를 모두 Queue에 저장해 놓았다가 특정 시점에서 모두 Dispath한다.
게임엔진은 사용자가 원하는 Event Type을 정의하고, 특정 Event Type을 처리하는 Callback을 등록하도록 인터페이스를 제공할 수 있다.

Event

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/** Engine API **/
class IEvent
{
public:
virtual const EventTypeID GetEventTypeID() const = 0;
};

template <typename T>
class Event : public IEvent
{
public:
static const EventTypeID EVENT_TYPE_ID;

virtual const EventTypeID GetEventTypeID() const override
{
return EVENT_TYPE_ID;
}
};

/** Client **/

class KeydownEvent : public Event<KeydownEvent>
{
...
};

사용자는 Event<T>를 상속하여 새로운 Event Type을 정의할 수 있다.

Read more

Shared global constants

여러 파일에서 공통으로 사용되는 전역 상수의 선언, 정의 방법에 따른 차이점.


Internal linkage를 갖는 전역 상수

constants.h:

1
2
3
4
5
6
7
8
#pragma once

namespace constants
{
constexpr double PI { 3.141592 };
constexpr float GRAVITY { 9.8 };
// ...
} // namespace constants

main.cpp:

Read more

Passkey Idiom

조금 더 강력하게 클래스 접근을 제한하는 방법.


Passkey Idiom

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Secure
{
int data;

public:
static std::shared_ptr<Secure> CreateSecureObj(int data);
class Key
{
friend std::shared_ptr<Secure> Secure::CreateSecureObj(int data);
Key() {};
};

explicit Secure(const Key& key, int data) : data{data} {};
};

std::shared_ptr<Secure> Secure::CreateSecureObj(int data)
{
return std::make_shared<Secure>(Secure::Key(), data);
}

Usage

1
2
3
auto pSecure1 = Secure::CreateSecureObj(10); // OK
auto pSecure2 = std::make_shared<Secure>(Secure::Key(), 10); // Error
auto pSecure3 = new Secure(Secure::Key(), 10) // Error



Read more