Company
교육 철학

LV02 h/.cpp 파일 분리, 생성자, 소멸자 (Header/CPP Split, Ctors/Dtors)

이 강의에서는 하나의 예제(Player 클래스)로 아래를 한 번에 연습합니다.
.h / .cpp 분리(선언/정의 분리)
생성자(Constructor): 기본/매개변수/복사 생성자
소멸자(Destructor)
헤더 가드(Header Guard)

1) 헤더(.h)와 소스(.cpp)를 왜 분리하나요?

프로그램 규모가 커질수록 모든 코드를 한 파일에 넣으면 읽기/수정/재사용이 어려워집니다.
헤더 파일(.h): “무엇을 제공하는지”를 적는 곳
클래스 선언
함수 원형(프로토타입)
상수/타입 정의
소스 파일(.cpp): “어떻게 동작하는지”를 적는 곳
함수 구현
클래스 메서드 정의

2) 예제 프로젝트 구성(딱 1개 예제로 끝내기)

아래 3개 파일이 하나의 예제입니다.
player.h
player.cpp
main.cpp

3) player.h (선언부) — 헤더 가드 포함

#ifndef PLAYER_H #define PLAYER_H #include <iostream> class Player { public: // (1) 기본 생성자 Player(); // (2) 매개변수 생성자 Player(const char* name, int height); // (3) 복사 생성자 Player(const Player& another); // (4) 소멸자 ~Player(); void Display(); private: char mName[256]; int mHeight; }; #endif
C++
복사
Header Guard 작동 원리
#ifndef PLAYER_H : PLAYER_H가 아직 정의되지 않았다면
#define PLAYER_H : 지금 정의해두고
헤더 내용을 포함
#endif : 조건부 컴파일 종료
이 구조 덕분에 같은 헤더가 여러 번 include 되더라도 중복 정의 오류를 막을 수 있습니다.

4) player.cpp (구현부) — 생성자/복사 생성자/소멸자 구현

#include "player.h" #include <cstring> // (1) 기본 생성자: 아무 값도 안 주고 만들면 이게 호출됨 Player::Player() { strcpy(mName, "나달"); mHeight = 183; } // (2) 매개변수 생성자: 이름/키를 받아서 초기화 Player::Player(const char* name, int height) { // 문자열 복사(직접 복사 버전) int len = strlen(name); for (int i = 0; i < len; i++) mName[i] = name[i]; mName[len] = '\0'; mHeight = height; } // (3) 복사 생성자: 다른 Player로 새 Player를 만들 때 호출 Player::Player(const Player& another) { strcpy(mName, another.mName); mHeight = another.mHeight; std::cout << "복사 생성자 호출: " << mName << std::endl; } // (4) 소멸자: 객체 수명이 끝나면 자동 호출 Player::~Player() { std::cout << mName << " 객체가 소멸되었습니다." << std::endl; } void Player::Display() { std::cout << "선수의 이름: " << mName << std::endl; std::cout << "선수의 키: " << mHeight << "cm" << std::endl; }
C++
복사

5) main.cpp (테스트 코드) — 생성/복사/소멸 흐름 확인

#include "player.h" int main() { std::cout << "=== 프로그램 시작 ===" << std::endl; // 1) 매개변수 생성자 Player federer("페더러", 184); federer.Display(); std::cout << std::endl; // 2) 복사 생성자 Player nadal(federer); nadal.Display(); std::cout << "=== 프로그램 종료 ===" << std::endl; // 지역 객체는 생성 역순(LIFO)으로 소멸 return 0; }
C++
복사

6) 생성자/복사 생성자/소멸자 핵심 정리

생성자(Constructor)
객체가 만들어질 때 자동 호출
클래스 이름과 동일
반환 타입 없음
오버로딩 가능(매개변수 다르면 여러 개 가능)
디폴트 생성자(Default Constructor)
매개변수 없이 호출 가능한 생성자
생성자를 하나도 안 만들면 컴파일러가 자동으로 만들기도 함
하지만 “매개변수 생성자”를 하나라도 직접 만들면, 컴파일러가 디폴트 생성자를 자동으로 안 만들어주는 경우가 많아서 직접 정의하는 습관이 안전함
복사 생성자(Copy Constructor)
다른 객체로 새 객체를 만들 때 호출
형태: Player(const Player& another)
호출 예: Player b(a);
소멸자(Destructor)
객체 수명이 끝나면 자동 호출
형태: ~Player()
클래스당 1개만 존재

7) 자주 실수(체크)

Player nadal();객체 생성이 아니라 함수 선언으로 해석될 수 있음
객체를 만들려면 Player nadal; 처럼 괄호를 빼는 습관
new[] 로 할당한 배열은 delete[] 로 해제
(이 페이지에서는 동적 할당 예제는 다루지 않음)