프렌드(friend)
클래스 외부의 함수 또는 다른 클래스를 friend로 선언하 면 클래스 내부의 데이터나 함수에 접근권한을 부여함
예)class Employee{
friend void e_print(Employee &); // 외부함수 friend class Manager; // 외부 클래스 friend void CEO::emp(Employee &);
// 외부 클래스 멤버함수 :
};
프렌드(friend) 유형 - 외부 전역 함수
- 외부 클래스의 멤버함수
- 외부 클래스 : 선언된 클래스 내부의 모든 멤버함수가 프 렌드가 됨
프렌드(friend) 사용법
- 프레드 선언은 클래스 접근권한과 무관하므로 어디든 선언할 수 있으나, 주로 앞부분에 선언함
- 프렌드로 선언된 외부함수 또는 클래스의 멤버함수는 클래스 내부의 모든 멤버변수나 멤버함수에 접근할 수 있음
// 프렌드 함수 프로그램
#include <iostream>
#include <string>
using namespace std;
class Employee{
friend void g_print(Employee &);
int id_no;
string e_name;
public:
Employee(int no, string name){
id_no = no; e_name = name;}
void e_print();
};void Employee::e_print(){
cout << "* 사번: " << id_no;
cout << " 이름: " << e_name;
return; }
void g_print(Employee &e){
cout << "* 사번: " << e.id_no;
cout << " 이름: " << e.e_name;
return;
}
int main()
{ Employee a(2002101, "홍길동");
Employee b(2012010, "이몽룡");
a.e_print(); b.e_print();
g_print(a); g_print(b);
return 0;
}
연산자 중복
C++ 본래의 연산자를 클래스로 정의된 객체들에도 사용 할 수 있도록 하여, 프로그램 작성과 가독성을 높임
연산자 중복의 특성
- C++ 본래의 연산자만 중복 가능함
※ 모든 연산자가 가능한 것은 아님(3항 연산자 등) 대입, 산술, 관계, 논리, 증감, 입출력 등이 가능함 - 연산자는 함수 형태로 구현
- 반드시 클래스와 관계가 있음 - 피연산자의 수를 바꿀 수 없음 - 연산우선순위를 바꿀 수 없음
멤버 함수로 연산자 중복 구현
형식)반환형 operator연산자(매개변수); //함수 원형
- 이항연산자의 매개변수는 1개, 단항연산자는 없음
전역 함수로 연산자 중복 구현
형식)반환형 operator연산자(매개변수); //함수 원형 - 이항연산자의 매개변수는 2개, 단항연산자는 1개 - 해당 클래스에 프렌드 함수로 선언
// 연산자 중복(1) 프로그램
#include <iostream>
using namespace std;
class Term{
int year, month;
public:
Term(int y=0, int m=0):
year(y), month(m){ } Term Add(Term &);
void t_print();
};Term Term::Add(Term &d){
Term t;
t.year = year + d.year;
t.month = month + d.month;
if(t.month > 12){
t.month -= 12;
t.year++;
}return t;
}
void Term:: t_print()
{ cout << year << "년 ";
cout << month << "개월\n";
return;
}
int main()
{ Term a(2,5), b(3,8), c;
c = a.Add(b);
c.t_print();
return 0;
}
// 연산자 중복(2) 프로그램
#include <iostream>
using namespace std;
class Term{
friend Term Add(Term&, Term&);
friend void t_print(Term &);
int year, month;
public:
Term(int y=0, int m=0):
year(y), month(m){ }
};Term Add(Term &d1, Term &d2){
Term t;
t.year = d1.year + d2.year;
t.month = d1.month + d2.month;
if(t.month > 12){
t.month -= 12;
t.year++;
}return t;
}
void t_print(Term &t)
{ cout << t.year << "년";
cout << t.month << "개월\n";
return;
}
int main()
{ Term a(2,5), b(3,8), c;
c = Add(a, b);
t_print(c);
return 0;
}
// 연산자 중복(3) 프로그램
#include <iostream>
using namespace std;
class Term{
friend void t_print(Term &);
int year, month;
public:
Term(int y=0, int m=0):
year(y), month(m){ } Term operator+(Term &);
};Term Term::operator+(Term &d){
Term t;
t.year = year + d.year;
t.month = month + d.month;
if(t.month > 12){
t.month -= 12;
t.year++;
}return t;
}
void t_print(Term &t)
{ cout << t.year << "년";
cout << t.month << "개월\n";
return;
}
int main()
{ Term a(2,5), b(3,8), c;
c = a + b;
t_print(c);
return 0;
}
// 연산자 중복(4) 프로그램
#include <iostream>
using namespace std;
class Term{
friend Term operator+(Term&, Term&);
friend ostream& operator<<(ostream&
os, const Term &);
int year, month;
public:
Term(int y=0, int m=0):
year(y), month(m){ }
};Term operator+(Term &d1, Term &d2){
Term t;
t.year = d1.year + d2.year;
t.month = d1.month + d2.month;
if(t.month > 12){
t.month -= 12; t.year++;
}return t;
}
ostream& operator<<(ostream& os,
const Term &t) { os << t.year << "년";
os << t.month << "개월\n";
return os;
}
int main()
{ Term a(2,5), b(3,8), c;
c = a + b;
cout << c;
return 0;
}
멤버 함수로 연산자 중복 구현 예) + 연산자
class C_name{
int var;
C_name operator+(C_name&); //함수 원형: };
C_name C_name::operator+(C_name &op2) // 함수 구현 { C_name temp;
temp.var = var + op2.var;
return temp;
}
멤버 함수로 연산자 중복 구현 예) == 연산자
class C_name{
int var;
bool operator==(C_name&); //함수 원형: };
bool C_name::operator==(C_name &op2) // 함수 구현 { if(var == op2.var)
return tree;
elsereturn false;
}
멤버 함수로 연산자 중복 구현 예) += 연산자
class C_name{
int var;
C_name operator+=(C_name&); //함수 원형: };
C_name C_name::operator+=(C_name &op2) // 함수 구현 { var += op2.var;
return *this;
}
멤버 함수로 연산자 중복 구현 예) 전위 ++ 연산자
class C_name{
int var;
C_name operator++(); // 함수 원형(매개변수 없음): };
C_name C_name::operator++() // 함수 구현 { var++;
return *this;
}
※ 논리연산자 !도 반환형을 bool로 바꾸어 같은 형식으로 구현
멤버 함수로 연산자 중복 구현 예) 후위 ++ 연산자
class C_name{
int var;
C_name operator++(int); // 함수 원형(매개변수 int 추가): };
C_name C_name::operator++(int x) // 함수 구현
{ C_name temp = *this; // 객체의 이전 상태 저장 var++;
return temp;
※ 매개변수 x는 단지 후위 연산자임을 표시하기 위한 용도임}
전역 함수로 연산자 중복 구현 형식)
class C_name{
friend ostream& operator<<(ostream& os, const C_name&);
// 함수 원형(friend 함수 추가) }; :
ostream& operator<<(ostream& os, const C_name& p) { os << p.var << endl;
return os; // ostream 참조자 반환 }
※ 입출력연산자 >>와 <<는 멤버 함수로 구현은 불가함
전역 함수로 연산자 중복 구현 형식)
class C_name{
friend istream& operator>>(istream& in, C_name&);
// 함수 원형(friend 함수 추가) }; :
istream& operator>>(istream& in, C_name& p) { in >> p.var;
if(!in) p.var = 0; // 입력 오류 처리
return in; // istream 참조자 반환 }