C++ Rookiss Part1 C++ 프로그래밍 입문 : 타입 변환(포인터)
🙇♀️타입 변환 (포인터)
🪐복습
// Stack [ type(4) dbid(4) dummy(4096) ]
Item item;
// Stack [ 주소(4~8) ] -> Heap [ type(4) dbid(4) dummy(4096) ]
Item* item2 = new Item();
포인터로 만들어준 것은 주소값만 있기 때문에 소멸자가 자동으로 만들어지지 않는다. delete
를 해줘야 한다. 해주지 않으면 메모리 누수가 일어난다.
void TestItem(Item item)
{
}
void TestItemPtr(Item* item)
{
}
TestItem(item);
TestItem(*item2);
TestItemPtr(&item);
TestItemPtr(item2);
헷갈리지만 포인터를 매개변수로 받는 함수의 사용법 익혀두자.
TestItem
의 경우 복사 되는 함수지만 새로운 객체를 만들어 내는 것은 같기 때문에 복사 생성자가 만들어진다.
TestItemPtr
은 원본을 그대로 쓰는거 이므로 복사 생성자가 없다.
// 배열
{
cout << "------------------------------" << endl;
// 진짜 아이템이 100개 있는 것 (스택 메모리에 올라와 있는)
Item item3[100] = { };
cout << "------------------------------" << endl;
// 아이템이 100개 있을까?
// 아이템을 가리키는 바구니가 100개. 실제 아이템은 1개도 없을 수도 있음
Item* item4[100] = {};
for (int i = 0; i < 100; i++)
item4[i] = new Item();
cout << "------------------------------" << endl;
for (int i = 0; i < 100; i++)
delete item4[i];
cout << "------------------------------" << endl;
}
item3
는 실제로 아이템이 있지만 item4
는 주소가 담긴 바구니만 100개다.
item4
에 아이템을 넣기 위해서 하나하나 동적할당을 이용해 넣어주고 delete
도 해줘야 한다.
🙇♀️타입 변환 (포인터)
- 명시적으로 변환 할 때는 항상 조심해야 한다
- 암시적으로 변환이 가능하다면 안전하다?
-
항상 암시적으로만 사용할 수 없다.
- 상속 관계에 있을 때 최상위 부모의 소멸자는 virtual을 붙여야한다.
- 원래는 자식의 타입마다 delete를 해야 하는데 virtual을 붙여서 가상함수로 만들면 delete부모;를 해도 자식까지 알아서 delete된다.
결론
- 포인터 vs 일반 타입 : 차이를 이해하자
- 포인터 사이의 타입 변환(캐스팅)을 할 때는 매우 매우 조심해야한다.
- 부모-자식 관계에서 부모 클래스의 소멸자에는 까먹지 말고 virtual을 붙이자!!!!