1. 연산자 오버로딩의 보완
연산자 오버로딩 시 파라미터 순서는 사용자의 입력 순서와 일치해야 합니다. 예를 들어, operator<<는 왼쪽 피연산자(출력 스트림)가 먼저 온다는 규칙을 따릅니다.
- 일반 멤버 함수로 오버로딩할 경우, 첫 번째 인자는
this포인터입니다. - 입력/출력 스트림 연산자(
<<,>>)는 전역 함수로 정의하는 것이 일반적입니다.
예시: 출력 연산자 오버로딩
class Date {
private:
int year, month, day;
public:
Date(int y, int m, int d) : year(y), month(m), day(d) {}
// 멤버 함수 형태 - this를 통해 접근
void print(std::ostream& os) const {
os << year << "년 " << month << "월 " << day << "일" << std::endl;
}
};
// 전역 함수로 선언 (스트림과 객체 간의 연산)
std::ostream& operator<<(std::ostream& out, const Date& d) {
out << d.year << "년 " << d.month << "월 " << d.day << "일";
return out;
}
2. 친구 함수 (Friend Functions)
친구 함수는 특정 클래스의 비공개 멤버에 접근할 수 있는 특수한 함수입니다. 이는 클래스의 캡슐화를 깨뜨리지만, 필요 시 성능이나 기능 구현을 위해 유용합니다.
주요 목적
- 성능 최적화: 반복적인 접근이 필요한 상황에서 직접 멤버에 접근하여 복사나 간접 호출을 줄임.
- 외부 기능 확장: 클래스 외부에서 수행되어야 하는 연산을 클래스 내부로 통합하기 위한 수단.
선언 및 정의 방법
클래스 내부에서 friend 키워드로 선언하고, 외부에서 일반 함수처럼 정의합니다.
class Time {
private:
int hour, minute;
public:
Time(int h, int m) : hour(h), minute(m) {}
// 친구 함수 선언
friend std::ostream& displayTime(std::ostream& os, const Time& t);
friend std::istream& inputTime(std::istream& is, Time& t);
};
// 친구 함수 정의
std::ostream& displayTime(std::ostream& os, const Time& t) {
os << t.hour << "시간 " << t.minute << "분";
return os;
}
std::istream& inputTime(std::istream& is, Time& t) {
is >> t.hour >> t.minute;
return is;
}
주의 사항
- 단방향 관계: 친구 함수는 클래스 내부에 접근 가능하지만, 그 반대는 불가능.
- 전달 불가: 친구 관계는 전파되지 않음.
- 캡슐화 손상 위험: 과도한 사용은 코드 유지보수성 저하를 초래.
3. const 멤버 함수
멤버 함수에 const를 붙이면 해당 함수가 객체 상태를 변경하지 않음을 컴파일러에게 알립니다.
기능
- 읽기 전용 연산 지원: 데이터 조회만 가능한 함수에 적합.
- const 객체 호출 가능:
const로 선언된 객체는 오직const멤버 함수만 호출 가능.
정의 방식
함수 선언 뒤에 const 키워드 추가
class Point {
private:
int x, y;
public:
Point(int a, int b) : x(a), y(b) {}
// const 멤버 함수
void show() const {
std::cout << "x=" << x << ", y=" << y << std::endl;
}
};
4. 초기화 리스트 (Initialization List)
생성자에서 멤버 변수를 초기화할 때 사용되는 문법으로, 효율적인 초기화를 보장합니다.
장점
- 기본 생성자 호출 생략: 기본값이 없는 타입(예: 참조, 상수)은 반드시 초기화 리스트에서 설정.
- 성능 향상: 복사 생성 없이 바로 초기화 가능.
- 멤버 변수 순서 중요: 초기화 리스트의 순서는 멤버 변수 선언 순서와 일치해야 함.
예제
class StackContainer {
private:
std::stack<int> pushStack;
std::stack<int> popStack;
size_t count;
const int capacity;
public:
StackContainer(size_t cap = 10)
: pushStack(cap),
popStack(cap),
count(0),
capacity(cap) {} // const 멤버는 반드시 초기화 리스트에서 설정
};