자료구조 & 알고리즘 시리즈
우리가 살아가는 현실 세계는 수많은 객체들로 구성되어 있습니다. 고양이는 울고, 사람은 걷고, 자동차는 달립니다. 객체 지향 프로그래밍(Object-Oriented Programming, OOP)은 이런 현실 세계의 구조를 그대로 본떠 만든 프로그래밍 방식입니다. 프로그램을 하나의 거대한 절차가 아닌 독립적인 객체들의 협력으로 구성함으로써 더 직관적이고 유지보수하기 쉬운 코드를 만들 수 있습니다.
객체지향 프로그래밍(OOP)은 현실 세계의 구조를 본떠 만든 프로그래밍 방식입니다. 우리가 사는 세상이 사람, 자동차, 고양이처럼 객체로 구성되어 있듯이, 객체지향도 프로그램을 객체 단위로 나누어 설계합니다.
class Circle {
public:
int radius; // 원의 반지름 (속성)
int calcArea() { // 원의 면적을 계산하는 기능
return 3.14 * radius * radius; // 원의 면적 공식 πr²
}
};
Circle이라는 클래스(설계도)를 정의하여 radius라는 속성(데이터)과 calcArea()라는 기능(메서드)을 가진 객체(Object)를 만들 수 있습니다.
⚠️ 주의: 클래스는 단순한 변수 묶음이 아니라 기능(함수)까지 포함합니다.
C++에서 프로그램이 점점 커지고 복잡해질수록, 클래스의 선언(인터페이스)과 구현(기능)을 분리해서 관리하는 것이 중요합니다. 이렇게 하면 코드를 더 읽기 쉽게 만들고 수정하거나 유지보수할 때 실수 가능성을 줄일 수 있습니다.
C++에서는 이를 위해 위와 같은 확장자를 사용합니다.
// Circle.h
class Circle {
public:
Circle(double r); // 생성자 선언
double calcArea(); // 면적 계산 함수 선언
private:
double radius; // 반지름 저장 변수
};
// Circle.cpp
#include "Circle.h"
#include <cmath>
Circle::Circle(double r) : radius(r) {} // 생성자 정의 (초기화 리스트 사용)
double Circle::calcArea() {
return M_PI * radius * radius; // cmath의 PI 사용해 면적 계산
}
클래스를 설계할 때는 위처럼 헤더(.h)에 인터페이스, 소스(.cpp)에 구현을 나눠서 작성하는 것이 좋은 습관입니다.
⚠️ 주의: 헤더 파일에는 함수의 정의가 아니라 선언만 작성해야 합니다. 구현까지 써버리면 중복 정의 오류가 발생할 수 있습니다.
⚠️ 주의: 헤더 파일은 #ifndef, #define, #endif 전처리기를 이용해 중복 포함을 방지해야 합니다.
⚠️ 주의: .cpp 파일에는 반드시 해당 클래스의 헤더 파일을 #include 해야 합니다.
C++에서 객체지향 프로그래밍(OOP)의 핵심은 객체의 상태(데이터)를 안전하게 관리하고 객체의 생성과 소멸 과정을 명확히 제어하는 것입니다. 이때 사용하는 중요한 함수들이 바로 생성자, 소멸자, 그리고 접근자/설정자입니다.
#include <iostream>
using namespace std;
class Student {
private:
string name; // 이름 (외부에서 직접 접근 불가)
int age; // 나이
public:
// 생성자
Student(string n, int a) {
name = n;
setAge(a); // setter 통해 유효성 검사
}
// 소멸자
~Student() {
cout << "학생 객체가 삭제됩니다: " << name << endl;
}
// 정보 출력 함수
void displayInfo() {
cout << "이름: " << name << ", 나이: " << age << endl;
}
// Setter (나이 설정)
void setAge(int a) {
if (a >= 0) age = a;
else cout << "⚠️ 나이는 0 이상이어야 합니다!" << endl;
}
// Getter (나이 조회)
int getAge() const {
return age;
}
};
Student(std::string n, int a);
생성자는 Student s("Alice", 20); 처럼 객체를 만들 때 자동 실행되며, name = "Alice", age = 20으로 초기화합니다.
~Student();
프로그램 종료 시나 delete 명령으로 객체가 삭제될 때 실행됩니다. 디버깅용 메시지를 출력하거나 자원을 해제하는 데 유용합니다.
객체 내부 데이터를 외부에서 직접 수정하지 못하도록 보호(private)하고, 대신 공식적인 함수로 간접 접근하게 하는 방식입니다.
💡 Tip: 캡슐화(Encapsulation)
이런 식으로 데이터를 외부로부터 보호하고, 공식적인 함수만으로 제어하는 것을 캡슐화라고 합니다.