Class는 C++에서 객체 지향 프로그래밍(OOP)의 핵심적인 개념으로, 객체를 만들기 위한 틀(blueprint) 또는 설계도 역할을 한다. 클래스는 데이터와 그 데이터를 다루는 함수를 하나의 단위로 묶어준다.
클래스의 구성 요소
클래스는 크게 두 가지로 구성됨.
- 멤버 변수 (Member Variables): 객체가 가지는 속성(상태)을 나타냅니다. 예를 들어, Car 클래스라면 color, speed 같은 변수들이 멤버 변수가 된다.
- 멤버 함수 (Member Functions): 객체가 할 수 있는 동작(행동)을 정의합니다. 예를 들어, Car 클래스라면 accelerate(), brake() 같은 함수들이 멤버 함수가 된다.
클래스와 객체의 차이
- 클래스: 붕어빵을 만드는 '틀' 그 자체.
- 객체 (Object): 그 틀로 찍어낸 실제 '붕어빵'.
클래스는 일종의 사용자 정의 자료형이며, 이 자료형을 이용해 메모리에 할당된 실체를 인스턴스(instance) 또는 객체라고 부른다. 하나의 클래스로 여러 개의 객체를 만들 수 있다.
클래스 사용 예시
#include <iostream>
#include <string>
// Car 클래스 정의
class Car {
public: // 접근 지정자: public은 외부에서 접근 가능
// 멤버 변수
std::string color;
int speed;
// 멤버 함수
void accelerate() {
speed += 10;
std::cout << "가속! 현재 속도: " << speed << std::endl;
}
void brake() {
if (speed >= 10) {
speed -= 10;
}
std::cout << "감속! 현재 속도: " << speed << std::endl;
}
};
int main() {
// Car 클래스의 객체 생성
Car myCar;
// 멤버 변수 초기화
myCar.color = "Red";
myCar.speed = 0;
// 멤버 함수 호출
myCar.accelerate(); // "가속! 현재 속도: 10" 출력
myCar.accelerate(); // "가속! 현재 속도: 20" 출력
myCar.brake(); // "감속! 현재 속도: 10" 출력
return 0;
}
Car는 클래스이고, myCar는 Car 클래스로 만들어진 객체.
myCar는 color와 speed라는 속성을 가지며, accelerate()와 brake()라는 행동을 수행할 수 있다.
Getter와 Setter: 객체의 '문지기'
Getter와 Setter는 클래스(객체)의 멤버 변수(속성)에 직접 접근하지 않고, 정해진 함수를 통해서만 접근하게 만드는 방법.
마치 중요한 정보가 들어있는 방에 문지기를 두는 것과 같다.
왜 사용하는가?
직접 변수에 접근하는 대신, 왜 굳이 함수(문지기)를 거쳐야 할까?
- 데이터 보호 (캡슐화): 멤버 변수의 값이 의도치 않게 변경되는 것을 막을 수 있다. 예를 들어, 나이를 나타내는 변수에 음수 값이 들어가는 것을 막고 싶을 때 setter 함수 안에서 유효성 검사를 할 수 있다.
- 유연성: 나중에 변수 이름을 바꾸더라도, getter와 setter 함수 이름은 그대로 유지할 수 있다. 이렇게 하면 변수 이름을 바꾸더라도 그 변수를 사용하는 다른 코드들을 수정할 필요가 없어서 편리하다.
1. Getter (정보를 '가져오는' 역할)
'Getter'는 멤버 변수에 저장된 값을 읽어오는 함수다. 보통 get이라는 접두사를 붙여서 만든다.
- 역할: "이 방에 있는 나이가 몇 살인지 알려줘!"
int getAge() {
return age;
}
2. Setter (정보를 '설정하는' 역할)
'Setter'는 멤버 변수의 값을 변경하는 함수다. 보통 set이라는 접두사를 붙여서 만든다.
- 역할: "이 방에 있는 나이를 25살로 바꿔줘." (이때 25가 음수가 아닌지 검사할 수 있다.)
void setAge(int newAge) {
if (newAge > 0) { // 유효성 검사
age = newAge;
}
}
[예시]
Person 클래스를 통해 직접 접근할 때와 getter/setter를 사용할 때의 차이를 비교
#include <iostream>
class Person {
private: // private은 외부에서 직접 접근 불가
int age;
public:
// Setter: 값을 설정하는 함수
void setAge(int newAge) {
if (newAge >= 0) { // 음수 나이를 막는 유효성 검사
age = newAge;
} else {
std::cout << "나이는 음수가 될 수 없습니다." << std::endl;
}
}
// Getter: 값을 읽어오는 함수
int getAge() {
return age;
}
};
int main() {
Person p;
// Setter를 사용하여 안전하게 값 설정
p.setAge(25);
std::cout << "현재 나이: " << p.getAge() << std::endl; // 출력: 25
// 유효하지 않은 값 설정 시도
p.setAge(-10); // "나이는 음수가 될 수 없습니다." 출력
std::cout << "변경 후 나이: " << p.getAge() << std::endl; // 출력: 25 (변경되지 않음)
return 0;
}
공부하다 재복습한 부분: void
void는 C++에서 '비어 있음' 또는 '아무것도 없음'을 의미하는 특별한 키워드. 주로 두 가지 주요 용도로 사용된다.
1. 함수가 반환하는 값이 없을 때
함수를 정의할 때, void는 그 함수가 어떤 값도 반환하지 않는다는 것을 나타냄. 예를 들어, 화면에 메시지를 출력하는 함수는 계산 결과를 반환할 필요가 없다.
#include <iostream>
void sayHello() { // 반환 타입이 void
std::cout << "안녕하세요!" << std::endl;
}
int main() {
sayHello(); // 함수를 호출하지만, 반환되는 값이 없음
return 0;
}
여기서 sayHello() 함수는 void를 반환 타입으로 사용하여 아무것도 반환하지 않음을 명시. 만약 int와 같은 다른 타입이었다면, return 문을 통해 해당 타입의 값을 반드시 반환해야 한다.
2. 함수가 인자를 받지 않을 때 (선택 사항)
함수가 어떤 인자도 받지 않는다는 것을 명확히 하고 싶을 때 void를 인자 목록에 사용하기도 한다.
C++에서는 인자 목록을 비워두는 것도 동일한 의미다.
// 두 가지 모두 동일한 의미를 가집니다.
void functionA(); // 인자 목록이 비어 있음
void functionB(void); // void를 명시적으로 사용
이 두 함수는 모두 인자를 받지 않는다.
3. 기타 용도
void 포인터는 모든 종류의 데이터 포인터를 가리킬 수 있는 범용 포인터로 사용된다. 이 또한 void의 중요한 용도 중 하나.
요약하자면, void는 함수가 값을 반환하지 않거나 인자를 받지 않는다는 것을 명확하게 하기 위해 사용. 코드를 읽는 사람에게 함수의 역할을 더 쉽게 이해시키는 데 도움을 줌.
'C++' 카테고리의 다른 글
| [TIL_C++]주어진 단어를 회전시켜 단어를 만들기 (2) | 2025.08.25 |
|---|---|
| [TIL_C++] OOP와 전직시스템 구현 과제 느낀점 (3) | 2025.08.22 |
| [TIL_C++] 상태창 구현해보기 (0) | 2025.08.20 |
| [TIL_C++]매개변수, 지역변수 / Call by Value, Ref / 메모리 할당 (3) | 2025.08.19 |
| [TIL_C++] 반복문 for, while 기초 (2) | 2025.08.18 |