본문 바로가기

C++

(85)
[C++] weak_ptr shared_ptr은 위와 같이 서로의 객체를 참조하고 있을 때 문제가 발생한다. 객체가 사라지려면 shared_ptr의 레퍼런스 카운트가 0이 되어야하는데 그러기 위해서는 상대방 객체가 파괴되어야 한다. 하지만 순환 참조를 이루고 있기 때문에 두 shared_ptr들은 해제되지 않는다. 이 문제를 해결하기 위해 weak_ptr을 사용한다.   std::string s; std::weak_ptr other; weak_ptr을 사용하는 예시로 먼저 weak_ptr을 선언한다.   void set_other(std::weak_ptr o) { other = o; } std::vector> vec; vec.push_back(std::make_shared("자원 1")); vec.push_back(std::m..
[C++] override 지정자 override 지정자는 가상함수를 재정의하는 함수를 지정할 수 있다. class BaseClass { virtual void funcA(); virtual void funcB() const; virtual void funcC(int = 0); void funcD(); }; class DerivedClass: public BaseClass { virtual void funcA(); // ok, works as intended virtual void funcB(); // DerivedClass::funcB() is non-const, so it does not // override BaseClass::funcB() const and it is a new member function virtual void ..
[C++] shared_ptr shared_ptr은 unique_ptr과 달리 여러개의 스마트 포인터가 하나의 객체를 같이 소유하는 경우에 사용한다. 이 경우에는 특정 자원을 몇개의 객체에서 가리키는지 추적한 다음 그 수가 0이 되면 해제를 해주는 방식이다. WinApi 게임 프레임워크에서 사용했던 레퍼런스 카운트와 같은 방식이다. 여러개의 shared_ptr들은 같은 객체를 가리킬 수 있고, 같은 객체를 가리키는 shared_ptr의 수만큼 레퍼런스 카운트가 증가한다. 참조 개수가 몇 개 인지는 use_count 함수를 통해 알 수 있다. shared_ptr들이 레퍼런스 카운트를 저장하는 방식은, 제어 블록을 이용한다. 제어 블록을 동적으로 할당하고 shared_ptr들이 필요한 정보를 공유한다. shared_ptr를 복사 생성할 ..
[C++] 스마트 포인터, unique_ptr C++의 포인터는 new로 할당을 하면, 반드시 delete로 해제해야 메모리 누수가 발생하지 않는다. 하지만 방대한 프로그램에서 프로그래머가 하나하나 빠지지 않고 할당된 포인터를 해제하는 것은 어려운 일이다. 그래서 만들어진 것이 스마트 포인터이다. 스마트 포인터는 포인터 객체이다. 포인터와 달리 객체는 함수가 종료될 때 자동으로 자신의 소멸자를 호출한다. 그래서 소멸자에 delete를 넣으면 메모리를 해제할 수 있고 이를 포인터에 적용한 것이다. Data* data = new Data(); Date* data2 = data; // data 의 입장 : 사용 다 했으니 소멸시켜야지. delete data; // ... // data2 의 입장 : 나도 사용 다 했으니 소멸시켜야지 delete data2..
[C++] 파일 입출력 - fopen_s, fread, fwrite 파일을 입출력할 때 파일의 데이터를 잠시 저장하기 위해 FILE 구조체를 사용한다. 우선 파일의 데이터를 저장하기 위한 파일 포인터를 만들고, fopen_s 함수로 파일을 열어 액세스를 준비한다. FILE* pFile = NULL; fopen_s(&pFile, strPath.c_str(), "rb"); fopen_s는 pFile에 strpath 경로의 파일을 "rb" 모드로 연다. "rb"는 파일 열기 모드 중 이진 파일을 읽기 전용(read binary)으로 연다는 뜻이다. 파일 열기에 성공했을시 0을 반환한다. fopen과의 차이점은 SDL검사를 지원하기 때문에 전처리기를 추가할 필요가 없다. fread(&m_vecPixel[0], sizeof(PIXEL), m_vecPixel.size(), pFil..
[C++] 가변 인자 템플릿 (variadic template) 가변 인자 템플릿은 가변 인자 함수와 마찬가지로 인수로 몇개가 올지 모르는 템플릿이다. 몇개의 키보드 입력을 받을지 모르는 AddKey로 가변 인자 템플릿을 만들어보겠다. template bool AddKey(const T& data) { if (!m_pCreateKey) m_pCreateKey = new KEYINFO; const char* pTType = typeid(T).name(); if (strcmp(pTType, "char") == 0 || strcmp(pTType, "int") == 0) { m_pCreateKey->vecKey.push_back((DWORD)data); } else { m_pCreateKey->strName = data; m_mapKey.insert(make_pair(m_p..
[C++] vector, list, map에 할당한 메모리 해제 winapi 실습중에 objList 이름의 list를 만들어 동적으로 할당한 객체들을 저장했다. 이렇게 vector나 list에 메모리를 동적으로 할당한 객체를 저장하면 clear()을 사용하는 것으로는 동적으로 할당한 메모리가 해제되지 않는다. 그래서 메모리를 해제하기 위하여 다음과 같은 코드를 작성하였다. template void Safe_Delete_VecList(T& p) { typename T::iterator iter; typename T::iterator iterEnd = p.end(); for (iter = p.begin(); iter != iterEnd; ++iter) { SAFE_DELETE((*iter)); } p.clear(); } SAFE_DELETE는 인수를 delete로 메모리..
[C++] 상속관계에서 복사 생성자 호출 상속관계에서 자식 클래스의 복사 생성자를 호출할 때 부모의 복사 생성자도 호출하기 위해서는 초기화 리스트를 사용해야 한다. CParent::CParent() { std::cout