Programming Languages/C++
객체 생성과 수명 주기
newclass
2025. 3. 28. 00:00
5.4 객체 생성과 수명 주기
5.4.1 스택 객체 vs 힙 객체
C++에서 객체는 스택(자동 메모리)이나 힙(동적 메모리)에 생성될 수 있습니다:
#include <iostream>
class SimpleClass {
public:
SimpleClass() {
std::cout << "객체 생성됨" << std::endl;
}
~SimpleClass() {
std::cout << "객체 소멸됨" << std::endl;
}
};
int main() {
// 스택 객체 (자동 메모리)
std::cout << "스택 객체 생성:" << std::endl;
SimpleClass stackObj; // 자동으로 생성/소멸
// 힙 객체 (동적 메모리)
std::cout << "힙 객체 생성:" << std::endl;
SimpleClass* heapObj = new SimpleClass(); // 명시적으로 생성
std::cout << "main 함수 마지막" << std::endl;
delete heapObj; // 명시적으로 소멸시켜야 함
return 0;
}
출력 결과:
스택 객체 생성:
객체 생성됨
힙 객체 생성:
객체 생성됨
main 함수 마지막
객체 소멸됨
객체 소멸됨
스택 객체 vs 힙 객체:
- 스택 객체: 블록이 끝나면 자동으로 소멸 (RAII 원칙)
- 힙 객체: 명시적으로 delete해야 소멸 (메모리 누수 위험)
5.4.2 정적 멤버(Static Members)
정적 멤버는 클래스의 모든 객체가 공유하는 멤버입니다:
#include <iostream>
#include <string>
class Student {
private:
std::string name;
int id;
static int totalStudents; // 정적 데이터 멤버 선언
public:
Student(const std::string& n) : name(n) {
id = ++totalStudents; // 새 학생이 생성될 때마다 증가
std::cout << name << " 학생 등록 (ID: " << id << ")" << std::endl;
}
~Student() {
--totalStudents;
std::cout << name << " 학생 제거" << std::endl;
}
// 정적 멤버 함수
static int getTotalStudents() {
return totalStudents;
}
void display() const {
std::cout << "이름: " << name << ", ID: " << id << std::endl;
}
};
// 정적 데이터 멤버 정의 및 초기화 (클래스 외부)
int Student::totalStudents = 0;
int main() {
std::cout << "처음 학생 수: " << Student::getTotalStudents() << std::endl;
// 객체 생성
Student s1("홍길동");
Student s2("김철수");
std::cout << "현재 학생 수: " << Student::getTotalStudents() << std::endl;
// 중괄호로 블록 생성
{
Student s3("이영희");
std::cout << "블록 내 학생 수: " << Student::getTotalStudents() << std::endl;
} // s3 소멸
std::cout << "블록 이후 학생 수: " << Student::getTotalStudents() << std::endl;
return 0;
}
정적 멤버의 특징:
- 클래스의 모든 객체가 공유
- 객체 생성 전에도 존재 (className::staticMember로 접근)
- 클래스 외부에서 정의 및 초기화 필요
- 정적 멤버 함수는 정적 데이터 멤버만 접근 가능
5.4.3 상수 멤버 함수(Const Member Functions)
상수 멤버 함수는 객체의 상태를 변경하지 않는 함수로, 함수 선언 끝에 const 키워드를 붙여 정의합니다:
class Date {
private:
int day, month, year;
public:
Date(int d, int m, int y) : day(d), month(m), year(y) {}
// 상수 멤버 함수 - 객체 상태 변경 불가
void display() const {
std::cout << day << "/" << month << "/" << year << std::endl;
// day = 10; // 오류: 상수 멤버 함수에서는 멤버 변수 수정 불가
}
// 비상수 멤버 함수 - 객체 상태 변경 가능
void setDay(int d) {
day = d;
}
};
int main() {
Date date(15, 8, 2023);
date.display(); // 상수 멤버 함수 호출
const Date constDate(25, 12, 2023);
constDate.display(); // 상수 객체는 상수 멤버 함수만 호출 가능
// constDate.setDay(26); // 오류: 상수 객체는 비상수 멤버 함수 호출 불가
return 0;
}
상수 멤버 함수의 장점:
- 코드의 의도를 명확하게 전달
- 상수 객체에서도 호출 가능
- 컴파일러의 최적화 기회 제공
- 프로그램의 안정성 향상