학습 목표
- 클래스의 역할 이해
- 클래스와 객체를 정의하고 활용
- 접근 제어자(public, private) 사용
1. 객체 없이 성적 관리 프로그램
- 기존 방식은 데이터 노출 및 재사용성 부족 문제 존재
double getAvg(int kor, int eng, int math) { return (kor + eng + math) / 3.0; }
int getMax(int kor, int eng, int math) { return max({kor, eng, math}); }
- 문제: 과목 추가 시 코드 수정 필요, 데이터가 외부에 노출됨.
2. 클래스 정의 및 멤버 구성
- 클래스 구조
- 멤버 변수: 데이터를 포함
- 멤버 함수: 동작 정의
class Student {
int kor, eng, math; // 멤버 변수
double getAvg(); // 멤버 함수
int getMaxScore();
};
.
3. 클래스 구현
- 클래스 내부 구현
class Student {
int kor, eng, math;
double getAvg() { return (kor + eng + math) / 3.0; }
int getMaxScore() { return max({kor, eng, math}); }
};
- 클래스 외부 구현
double Student::getAvg() { return (kor + eng + math) / 3.0; }
int Student::getMaxScore() { return max({kor, eng, math}); }
4. 접근 제어자
- public: 외부 접근 가능
- private: 외부 접근 불가
class Student {
public:
double getAvg();
int getMaxScore();
private:
int kor, eng, math;
};
5. Getter와 Setter
- 사용 이유: private 멤버 접근 및 수정
class Student {
public:
void setKor(int k) { kor = k; }
int getKor() { return kor; }
private:
int kor, eng, math;
};
6. 생성자(Constructor)
생성자는 객체가 생성될 때 호출되는 특수한 멤버 함수로, 클래스와 동일한 이름을 가지며 반환 타입이 없다. 생성자를 활용해 객체를 다양한 방식으로 초기화할 수 있으며, 이를 **생성자 오버로딩(Constructor Overloading)**이라고 한다.
#include <iostream>
#include <string>
using namespace std;
class Car {
string brand;
int year;
public:
Car() : brand("Unknown"), year(0) {} // 기본 생성자
Car(string b, int y) : brand(b), year(y) {} // 매개변수가 있는 생성자
void display() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
};
int main() {
Car car1; // 기본 생성자 호출
Car car2("Hyundai", 2023); // 매개변수가 있는 생성자 호출
car1.display();
car2.display();
return 0;
}
기본 생성자는 초기값을 설정하며, 매개변수가 있는 생성자는 입력받은 값을 기반으로 멤버 변수를 초기화한다.
7. 헤더와 소스 파일 분리
C++에서는 코드 가독성과 유지보수를 위해 클래스 선언과 구현을 분리하는 것이 일반적이다. 헤더 파일(.h)에는 클래스 선언을, 소스 파일(.cpp)에는 해당 클래스의 구현을 작성한다.
예제: Car 클래스 헤더와 소스 파일 분리
- Car.h (헤더 파일)
#ifndef CAR_H
#define CAR_H
#include <string>
using namespace std;
class Car {
string brand;
int year;
public:
Car();
Car(string b, int y);
void display();
};
#endif
- Car.cpp (소스 파일)
#include "Car.h"
#include <iostream>
using namespace std;
Car::Car() : brand("Unknown"), year(0) {}
Car::Car(string b, int y) : brand(b), year(y) {}
void Car::display() {
cout << "Brand: " << brand << ", Year: " << year << endl;
}
- main.cpp (메인 파일)
#include "Car.h"
int main() {
Car car1;
Car car2("Hyundai", 2023);
car1.display();
car2.display();
return 0;
}
위 구조에서는 클래스를 사용하는 코드를 main.cpp에 작성하며, Car.h와 Car.cpp가 각각 선언과 구현을 담당한다.
4. 결론
- 오늘 학습한 주요 내용:
- 생성자를 활용한 객체 초기화.
- 클래스 설계를 파일로 나누어 재사용성 및 유지보수성을 강화.
- 헤더 및 소스 파일 구조를 통한 효율적인 코드 관리.
- 생성자는 객체의 초기화를 간단하게 하고, 파일 분리 기법은 대규모 프로젝트에서 필수적이다.
'TIL > C++' 카테고리의 다른 글
챕터 2-2 : 템플릿 (1) | 2024.12.31 |
---|---|
챕터 2-1 : 자원 관리하기 (0) | 2024.12.30 |
C++ 추가 자료 (1) | 2024.12.27 |
챕터 1-3 : 객체지향 프로그래밍 (1) | 2024.12.26 |
챕터 1-1 : 프로그래밍 기초 (1) | 2024.12.23 |