이번 편의 목표: 객체가 만들어질 때 생성자가, 수명이 끝날 때 소멸자가 호출되는 순서를 확인합니다.
생성자는 객체의 멤버를 쓸 수 있는 상태로 만듭니다. 소멸자는 그 객체가 스코프를 벗어날 때 자동으로 호출됩니다. std::string 멤버가 가진 문자 메모리는 string의 소멸자가 돌려줍니다. Book이 그 해제를 다시 적지 않아도 됩니다.
#include <iostream>
#include <string>
class Book {
public:
Book(const std::string &title, int price) : title_(title), price_(price) {
std::cout << "생성 " << title_ << '\n';
}
~Book() {
std::cout << "소멸 " << title_ << '\n';
}
int price() const { return price_; }
private:
std::string title_;
int price_;
};
int main() {
Book original("개미", 12000);
Book copy = original;
std::cout << copy.price() << '\n';
return 0;
}생성 문장은 한 번만 나옵니다. Book copy = original은 우리가 만들지 않은 복사 생성자를 호출하고, string과 int를 멤버 단위로 복사합니다. 소멸 문장은 original과 copy에 대해 두 번 나옵니다. 나중에 만들어진 copy가 먼저 소멸합니다.
멤버가 string과 int뿐이므로 복사는 안전합니다. 여기에 12편처럼 malloc한 주소를 멤버로 직접 넣으면, 복사본과 원본이 같은 주소를 갖고 소멸자에서 두 번 해제하게 됩니다. 그 설계는 21편에서 소유권을 타입으로 옮기는 방법으로 막습니다. 멤버가 스스로 자원을 관리하면 복사와 소멸을 직접 만들지 않습니다.
직접 해 보기
main의 중괄호 안에 블록을 하나 더 만들고, 그 안에서만 Book을 생성하세요. 블록이 끝난 뒤의 출력보다 소멸 문장이 먼저 나와야 합니다.
해설
안쪽 블록이 끝나면 그 블록의 Book 소멸자가 즉시 호출됩니다. main이 끝나기를 기다리지 않습니다. 수명은 객체가 선언된 블록과 같습니다.
COMMENTS
댓글 0
이 글에 대한 의견이나 질문을 남겨 주세요.
댓글은 구글이나 카카오로 시작한 뒤에 남길 수 있습니다.
등록된 댓글이 없습니다.