프렌드 함수는 클래스 외부에서 정의된 함수로, 해당 클래스의 private 및 protected 멤버에 접근할 수 있습니다. 프렌드 함수는 friend 키워드를 사용하여 선언합니다.
전역 함수 : 객체를 사용하지 않고 호출
class Rect {
friend bool equals(Rect r, Rect s);
};
특정 클래스 멤버 함수 : 해당 클래스의 객체를 생성하여 호출
class Rect {
friend bool RectManager::equals(Rect r, Rect s);
};
다른 클래스 전체 : 해당 클래스의 객체를 생성하여 호출
class Rect {
friend class RectManager;
};
#include <iostream>
using namespace std;
// Rect 클래스의 전방 선언. Rect클래스가 선언되기 전에 먼저 참조되는 컴파일 오류를 막기 위한 선언문
class Rect;
bool externalEquals(Rect r, Rect s); // 외부(전역) 함수 선언
class RectManager {
public:
bool memberEquals(Rect r, Rect s); // 멤버 함수: 도형 크기 비교
void copy(Rect& dest, Rect& src); // 멤버 함수: 도형 복사
};
class Rect {
int width, height;
public:
Rect(int width, int height) : width(width), height(height) {} // 생성자
// 1. 외부 함수를 프렌드로 선언
friend bool externalEquals(Rect r, Rect s);
// 2. 특정 클래스 멤버 함수를 프렌드로 선언
friend bool RectManager::memberEquals(Rect r, Rect s);
// 3. 다른 클래스 전체를 프렌드로 선언
friend class RectManager;
};
// 1. 외부 함수 정의
bool externalEquals(Rect r, Rect s) {
return r.width == s.width && r.height == s.height; // private 멤버에 접근 가능
}
// 2. RectManager의 멤버 함수 정의
bool RectManager::memberEquals(Rect r, Rect s) {
return r.width == s.width && r.height == s.height;
}
// 3. RectManager의 멤버 함수 정의
void RectManager::copy(Rect& dest, Rect& src) {
dest.width = src.width;
dest.height = src.height;
}
int main() {
Rect a(3, 4), b(4, 5);
RectManager man;
// 외부 함수 호출
if (externalEquals(a, b))
cout << "externalEquals: equal" << endl;
else
cout << "externalEquals: not equal" << endl;
// RectManager 멤버 함수 호출
if (man.memberEquals(a, b))
cout << "memberEquals: equal" << endl;
else
cout << "memberEquals: not equal" << endl;
// RectManager 멤버 함수 호출 (copy)
man.copy(b, a);
if (man.memberEquals(a, b))
cout << "after copy: equal" << endl;
else
cout << "after copy: not equal" << endl;
return 0;
}
연산자 중복은 C++에서 기존 연산자에 새로운 의미를 부여하여 사용자 정의 타입에 대해 사용할 수 있도록 합니다. 이를 통해 코드의 가독성과 사용성을 높일 수 있습니다.
클래스의 멤버 함수로 구현
외부 함수로 구현하고 클래스에 프렌드 함수로 선언
리턴타입 operator연산자(매개변수리스트);
class Color {
public:
Color operator+(Color op2);
bool operator==(Color op2);
};
class Color {
public:
friend Color operator+(Color op1, Color op2);
friend bool operator==(Color op1, Color op2);
};

class Power {
int kick;
int punch;
public:
Power(int kick=0, int punch=0) : kick(kick), punch(punch) {}
Power operator+(Power op2); // + 연산자 함수 선언
};
//새로운 객체 'tmp'를 생성하여 두 객체의 값을 더해준다. 원래 객체는 수정되지 않고, 새로운 객체를 반환한다.
Power Power::operator+(Power op2) {
Power tmp;
tmp.kick = this->kick + op2.kick; // kick 값 더하기
tmp.punch = this->punch + op2.punch; // punch 값 더하기
return tmp;
}
단항 연산자는 피연산자가 하나뿐인 연산자로, 연산자 중복 방식은 이항 연산자의 경우와 거의 유사합니다.
++op, --op, !op, ~opop++, op--
class Power {
int kick;
int punch;
public:
Power(int kick=0, int punch=0) : kick(kick), punch(punch) {}
Power& operator++(); // 전위 ++ 연산자 함수 선언.
};
// 리턴타입 : 레퍼런스
Power& Power::operator++() {
kick++;
punch++;
return *this; // 변경된 객체 자신을 반환
}
int main() {
Power a(3,5), b; //a=(3,5), b=(0,0)
b=++a; //a=(4,6), b=(4,6)
}

class Power {
int kick;
int punch;
public:
Power(int kick=0, int punch=0) : kick(kick), punch(punch) {}
Power operator++(int); // 후위 ++ 연산자 함수 선언
};
Power Power::operator++(int) {
Power tmp = *this; // 증가 이전 객체 상태 저장
kick++;
punch++;
return tmp; // 증가 이전의 객체 반환
}
int main() {
Power a(3,5), b; //a=(3,5), b=(0,0)
b = a++; //a=(4,6), b=(3,5)
}
Power operator+(int op1, Power op2) {
Power tmp;
tmp.kick = op1 + op2.kick; // kick 값 더하기
tmp.punch = op1 + op2.punch; // punch 값 더하기
return tmp;
}
Power operator+(Power op1, Power op2) {
Power tmp;
tmp.kick = op1.kick + op2.kick; // kick 값 더하기
tmp.punch = op1.punch + op2.punch; // punch 값 더하기
return tmp;
}
#include <iostream>
using namespace std;
class Power {
int kick;
int punch;
public:
Power(int kick = 0, int punch = 0) : kick(kick), punch(punch) {}
void show() {
cout << "kick=" << kick << ", punch=" << punch << endl;
}
Power& operator<<(int n); // << 연산자 함수 선언
};
Power& Power::operator<<(int n) {
kick += n; // kick 값에 n 더하기
punch += n; // punch 값에 n 더하기
return *this; // 변경된 객체 자신을 반환
}
int main() {
Power a(1, 2);
a << 3 << 5 << 6; // << 연산자 사용
a.show(); // 결과 출력
}