CBase 클래스
이제부터 생성하는 모든 클래스는 CBase 클래스를 상속받게 될 것이다.
왜냐하면 객체의 레퍼런스 카운트를 저장할 것이기 때문이다.
객체가 참조당할 때 마다 레퍼런스 카운트가 증가하고 더 이상 참조하지 않으면 Safe_Release를 통해 감소시킨다.
Safe_Release를 했을 때 레퍼런스 카운트가 0이라면 아무도 객체를 참조하지 않는 것이므로 삭제할 수 있다.
unsigned long CBase::AddRef()
{
return ++m_dwRefCnt;
}
unsigned long CBase::Release()
{
return m_dwRefCnt--;
}
주의해야할 점은 AddRef함수는 레퍼런스 카운트가 증가되고 난 후의 값을 반환하고
Release는 레퍼런스 카운트가 감소되기 전 값을 반환한다. 왜일까?
만약 레퍼런스 카운트가 감소된 후 값을 반환한다면 레퍼런스 카운트가 1일 때
Release되는 경우와 0일때 Release되는 경우의 반환 값이 0으로 같을 것이다. 이런 경우를 구분하기 위해서이다.
소멸자 vs 함수
virtual ~CBase() = default; //소멸자
virtual void Free() = 0; // 함수 (자식 클래스에서 무조건 만들도록 순수가상함수로 선언)
CBase 클래스에서는 소멸자는 default (비어있는 기본 상태)로 지정하고 Free라는 함수를 이용한다.
이 Free라는 함수가 소멸자의 역할을 하게 되는데 굳이 왜 이렇게 하는 것일까?
우선 소멸자에 virtual 을 붙이면 자식 클래스의 소멸자가 먼저 호출되고 부모 클래스의 소멸자가 호출되는 것은 알 것이다.
편리하다고 생각할 수 있지만 소멸자의 호출 순서를 바꿀 수 없기 때문에 이 과정에서 문제가 발생할 수 있다.
void Free()
{
Parent::Free(); // __super::Free();
Free();
delete this;
}
Free함수를 이용하면 명시적으로 부모 클래스의 Free함수를 호출해야 한다는 번거로움이 있지만,
부모 소멸자와 자식 소멸자의 순서를 임의로 지정할 수 있다.
라이브러리 만들고 적용
라이브러리를 클라이언트에 가져와서 사용할 때, 라이브러리는 부품 같은 것이기 때문에 라이브러리를 수정하려고 하면 안된다. 그래서 헤더파일은 함수를 사용하기 위해 보여줘도 되지만 cpp파일은 수정하지 못하게 숨겨야 한다.
그래서 cpp는 라이브러리화해서 전달해야하고 그렇게 하기 위해서는 클래스를 보여주기용 클래스로 지정해줘야 한다.
class _declspec(dllexport) 라이브러리 클래스명
class _declspec(dllimport) 클라이언트 클래스명
라이브러리인지 클라이언트인지에 따라 클래스명 앞에 위 지정자를 붙여주면 얘는 라이브러리에서 export하는 클래스구나하면서 cpp파일을 라이브러리화하고 클라이언트에서 import하면 클래스를 사용할 수 있다.
링커 > 일반 > 추가 라이브러리 디렉터리 - 라이브러리 경로
링커 > 입력 > 추가 종속성 - lib파일 이름
라이브러리를 적용하기 위해 프로젝트 설정에서 라이브러리 경로와 lib 파일 이름을 추가해줘야 한다.
C/C++ > 일반 > 추가 포함 디렉터리 - 라이브러리 헤더파일 복사본 경로
라이브러리의 헤더파일을 이용하기 위해서는 라이브러리의 헤더파일 복사본이 필요하므로 경로를 지정한다.
이러면 귀찮은 게 두가지 있는데 1. 클래스마다 _declspec 로 지정해줘야 하는 것 2. 라이브러리에 변경이 있을 때마다 lib파일과 헤더파일을 새로 복사해야 한다는 것이다. 먼저 1번을 해결해보자.
#ifdef ENGINE_EXPORTS
#define ENGINE_DLL _declspec(dllexport)
#else
#define ENGINE_DLL _declspec(dllimport)
프로젝트를 DLL(동적 라이브러리)로 생성하면 C/C++ > 전처리기 정의에 일반 프로젝트와 다르게 ENGINE_EXPORTS가 추가되어 있다. 그래서 ENGINE_DLL을 DLL프로젝트인 경우 dllexport, 아닐 경우 dllimport로 지정해서 클래스명 앞에는 ENGINE_DLL로 통일해서 작성할 수 있게 할 수 있다.
//// xcopy .복사할 파일이 들어있는 경로 .복사받을 경로.
xcopy /y .\Engine\Public\*.h .\Reference\Headers\
xcopy /y .\Engine\Bin\*.lib .\Reference\Librarys\
xcopy /y .\Engine\Bin\*.dll .\Client\Bin\
2번은 프로젝트의 batch파일에서 xcopy를 이용해서 자동으로 헤더파일과 lib파일, dll파일을 복사할 수 있다.
/y는 덮어쓸 때 물어보지 않는 명령어이고 batch파일에 저렇게 작성해 놓으면 더블클릭만 하면 파일이 복사된다.
'Today I Learned' 카테고리의 다른 글
| 23. 05. 16 - Depth Buffer (0) | 2023.05.16 |
|---|---|
| 23. 05. 15 - 정적 라이브러리와 동적 라이브러리 외 (0) | 2023.05.15 |
| 23. 05. 11 - 프로젝트 파일 디렉터리 설정, 클래스 get/set 함수 지양 (0) | 2023.05.11 |
| 23.03.03 - 람다식, R-value Reference, 이동 생성자 (0) | 2023.03.03 |
| 23.02.28 - map (0) | 2023.02.28 |