동적 객체는 delete를 해줘야한다
동적 생성된 객체는 명시적으로 delete를 해줘야 삭제가 됩니다. 다른 객체들은 그 객체의 scope를 벗어나면 자동 삭제되지만 동적 생성은 아닙니다.
그러므로 반드시 delete를 해주어야 하는데요. 동적 생성된 객체의 주소를 저장하는 포인터는 그 포인터 변수의 scope를 벗어나면 자동 삭제됩니다. 이 경우 동적 생성된 객체의 주소를 잃어버리게 됩니다.
이렇게 주소를 잃어버리고 삭제되지 않은 동적 객체를 쓰레기라고 부릅니다. 이 누적된 쓰레기는 프로그램의 성능을 저하시킵니다.
class MyPoint {
public:
double x, y;
MyPoint() = default;
MyPoint(double a, double b) : x(a), y(b) {}
};
int main() {
MyPoint a(0, 0);
someFunc1(a);
MyPoint* r2 = someFunc2(a);
someFunc3();
}
void someFunc1(MyPoint s) {
MyPoint p(1, 2);
}
MyPoint* someFunc2(MyPoint s) {
MyPoint* ptr = new MyPoint(3, 4);
return ptr;
}
void someFunc3() {
MyPoint* ptr = new MyPoint(5, 6);
delete ptr;
}
처음 someFunc1의 s와 p는 동적 생성객체가 아니므로 이 함수가 종료되면 자동 삭제됩니다.
ptr이 가리키는 MyPoint 객체는 동적으로 생성되었습니다. 이 함수가 종료되면 포인터 변수 ptr은 자동으로 소멸됩니다. 하지만 이 객체의 주소를 return하므로 main함수가 이 객체의 주소를 갖게 됩니다. 문제가 없습니다.
somefunc3 함수가 종료되면 포인터 변수 ptr은 자동으로 소멸됩니다. 그러면 동적 생성된 객체의 주소를 아무도 기억하지 못합니다. 따라서 delete명령으로 이 객체를 삭제하지 않으면 쓰레기가 됩니다.
배열의 동적 배열
동적 배열을 생성하면 new는 배열의 주소가 아니라 배열의 첫 번째 원소의 주소를 반환합니다. 따라서 포인터의 타입이 int *, string *, Term * 입니다.
배열의 타입명을 입력하고 동적으로 생성합니다.
배열의 첫번째 칸은 반환해주는 것입니다. 지금까지는 어떤 객체를 동적 생성하면 주소 전체 를 리턴해주었지만 배열에 대한 포인터가 아니라 배열 전체가 아닌 첫 번재 원소의 주소를 하기 때문에 포인터의 타입이 배열 첫 번째 원소의 타입을 반환해줘야 하는 것입니다. (배열은 원래 예외가 많습니다)
Term* pta = new Term[10];
Term t1(2, 3), t2(4, 5), t3(6, 7);
이렇게 길이가 10인 Term타입의 배열을 동적 생성을 해주었습니다.
pta[0] = t1;
pta[1] = t2;
pta[2] = t3;
그렇다면 이렇게 배열의 첫 번째 원소의 주소인 pta를 마치 배열의 이름인 것처럼 사용을 할 수 있습니다.
for (int i = 0; i < 3; i++)
cout << pta[i].coef << ", " << pta[i].expo << endl;
이렇게도 할 수 있습니다.
int* pia = new int[10];
string* psa = new string[10];
Term* pta = new Term[10];
delete[] pia;
delete[] psa;
delete[] pta;
앞에 delete 앞에 []를 해주어야지 삭제가 됩니다. 이는 배열만의 특이한 규칙입니다.
'IT 프로그래밍 > 객체지향프로그래밍' 카테고리의 다른 글
객체의 복사와 삭제 (0) | 2024.06.17 |
---|---|
다항식 계산기 (code12. cpp 수정 (0) | 2024.06.16 |
동적 객체 생성 new 연산자 (0) | 2024.06.16 |
[C++]연산자 오버로딩 (0) | 2024.06.15 |
[C++] 다항함수 계산기 [5-2] (0) | 2024.06.15 |