공부 114

C++ const가 붙는 위치에 따른 의미변화

포인터 변수의 const는 붙는 위치에 따라 의미가 다르다. 아래 글은 Reference에 쓰여져 있는 포스팅이 정리가 잘 되어 있어서 인용했다. int const * p; // 1 int * const p; // 2 int const * const p; // 3 const int * p; // 4 p = (int *)0x1000; // 가 p++; // 나 *p = 100; // 다 a = *p; // 라 const는 바로 앞의 키워드에 대해 상수화가 이루어진다고 보면 된다. 단 예외적으로 4번은 앞에 아무 키워드도 없으니 뒤에 있는 키워드에 대해 상수화를 시킨다. 그래서 1 -> 값에 대한 상수화 2 -> 포인터에 대한 상수화 3 -> 값, 포인터 모두에 대한 상수화 4 -> 값에 대한 상수화 그래서..

공부/C || C++ 2021.09.01

C++ 변환 연산자(Conversion Operator)

C++ 클래스에서는 변환 연산자(Conversion operator)라는 특이한 함수를 연산자 오버로딩할 수 있다. 예를 들어서 아래와 같이 CSharedPtr을 구현한 상태라고 생각해보자. #pragma once template class CSharedPtr { public: CSharedPtr(): m_Ptr(nullptr) { } CSharedPtr(T* Ptr) { m_Ptr = Ptr; if (m_Ptr) m_Ptr->AddRef(); } CSharedPtr(const CSharedPtr& Ptr) { m_Ptr = Ptr.m_Ptr; if (m_Ptr) m_Ptr->AddRef(); } ~CSharedPtr() { if (m_Ptr) m_Ptr->Release(); } private: T* m..

공부/C || C++ 2021.08.28

C++ vector의 resize vs reserve

vector에는 resize 함수와 reserve 함수가 있다. 언뜻 보기에 같은 동작을 하는 것 처럼 보이지만 다른 동작을 하는 함수다. void resize (size_type n, value_type val = value_type()); vector는 미리 할당된 공간에 element를 채우면서, 할당된 공간이 모두 차면, 2배 크기의 새로운 공간을 할당해서 element를 옮겨준다. 여기서 말하는 '미리 할당된 공간'을 capacity라고 하며, 'element가 실제로 들어있는 공간'을 size라고 부른다. 예를 들어서 벡터에 미리 할당된 공간이 4개라고 가정하고, 1,2,3 각각을 vector에 push_back했다고 가정해보자. vector vec; vec.push_back(1); vec.p..

공부/C || C++ 2021.08.25

C++ 오버라이딩시 반환 타입을 자식 클래스 타입으로 하면 반환 타입이 다르게 오버라이딩 된다

일반적으로 부모클래스에 정의된 멤버 함수를 자식 클래스에서 재정의하는 것을 오버라이딩(overriding)이라고 하는데, 이 오버라이딩은 함수 이름, 매개 변수, 반환 타입까지 같아야 한다고 알고 있을 것이다. 하지만 아래 경우처럼 부모 클래스에서 정의한 함수를 자식 클래스에서 오버라이딩할 때, 그 오버라이딩 하려는 함수의 타입을 자식 클래스 타입으로 하면 오버라이딩 함수의 타입을 다르게 해도 오버라이딩이 가능하다(근본적으로는 타입이 다르다라고 할 순 없다. 이 경우 covariant한 타입이라고 표현을 하더라) class CParent { public: CParent(); virtual ~CParent(); CParent(const CParent& Parent); virtual CParent* Clon..

공부/C || C++ 2021.08.21

멀티 바이트/유니코드 문자열 만들어주기(sprintf_s, wsprintf)

실수 타입은 유니코드 문자열로 만들 수 없으므로 멀티 바이트 문자열로 만들어줘야 하는데 그때 사용할 수 있는 함수가 sprintf_s 함수이다. 오버로드된 다른 형태도 있다. 나의 경우 이렇게 사용해줬다. char FPSText[32] = {}; // 2번째 인자를 멀티 바이트 문자열 형태로 1번째 인자에 저장해준다 // GetFPS() 함수는 float타입을 리턴하는 함수 sprintf_s(FPSText, "FPS : %.5f", m_Timer->GetFPS()); 다른 타입들(ex. 정수형) 들은 wsprintf 함수로 유니코드 문자열로 만들어줄 수 있다. TCHARBulletCountText[32] = {}; // 두번째 인자로 첫번째 인자에 유니코드 문자열을 만들어주는 함수 wsprintf(Bul..

공부/WINAPI 2021.08.20

레지스터(Register) vs 레지스트리(Registry)

공부를 하던중 레지스트리가 나와서 레지스터랑 비슷한건가 생각하면서 찾아봤는데 레지스터랑은 관련 없는 별개의 단어 였다. 레지스터(Register) 우리가 흔히 아는 main memory, cache보다도 접근이 빠르지만 용량이 적은 기억장치. 시스템 프로그래밍 과목에서 assembly 배울 때 나왔던 범용 레지스터(General Purpose Register)도 레지스터다. reverse engineering 하면서 봤던 %eax, %esp 이런 녀석들이다. 레지스트리(Registry) 윈도우에서 시스템 구성 정보(ex. Main memory의 크기, 시스템 매개변수 등)를 저장하고 있는 데이터베이스로써, 부팅 시에 필요한 정보들을 담고 있다. WinAPI에서 RegisterMyClass 함수는 이 레지..

공부/그 외 2021.08.18

C++ return new(*this); 는 복사 생성자를 호출한다

프로젝트를 진행중에 prototype을 clone하는 코드를 작성해야 했는데 다음과 같은 방식으로 작성한 코드를 보았고 이게 과연 복사 생성자를 호출할지, 그냥 생성자를 호출할 지 궁금했다. CClass* CClass::Clone() { return new CClass(*this); } 내가 아는 복사 생성자의 호출 시기는 객체를 인자로 넘길 때 reference 형태가 아닌 value 형태로 넘길 때 객체를 값으로 반환할 때 객체를 생성과 동시에 기존에 존재하는 객체로 초기화 할 때 이렇게 3가지 인데, 저 3가지중에 어디에 해당되는지 확신이 없었다. 1, 2번은 당연히 아니고 3번이 의심돼서 아래와 같은 코드를 작성하고 직접 확인해보았다. //CClass.h class CClass { public: ..

공부/C || C++ 2021.08.17

C/C++ 파일 입출력

C 스타일 파일 입출력 errno_t fopen_s( FILE** pFile, const char *filename, const char *mode ); return : 성공 시 0을 리턴하고, 에러 발생 시 errno_t타입의 0이 아닌 값을 리턴 pFile : FILE타입(파일 스트림)의 이중 포인터 filename : 파일 이름. 파일 이름만 쓰고, visual studio에서 빌드 하면 프로젝트 파일이 있는 곳에 파일을 만든다 mode r : 파일 읽어오기 w : 파일 쓰기(만들기) a : 파일에 접근하여 이어 쓰기 r+ : 파일이 존재하면 해당 파일을 읽고 쓰기 가능하게 연다. 파일이 없으면 에러를 반환 w+ : 파일이 존재하면 해당 파일에 읽고 쓰기 가능하게 연다. 파일이 없으면 새로 만든다 ..

공부/C || C++ 2021.08.14