1. C++에서의 friend
1) friend 함수
- 클래스의 멤버 함수가 아닌 외부 함수
- 전역함수, 다른 클래스의 멤버함수
- friend 키워드로 클래스 내에 선언된 함수 : friend 함수라고 부름
- 클래스 정의 안쪽에 friend 키워드를 쓰고 함수의 선언을 적어줌
- 클래스의 모든 멤버를 접근할 수 있는 권한 부여
- friend 선언의 필요성
- 클래스의 멤버로 선언하기에는 무리가 있고, 클래스의 모든 멤버를 자유롭게 접근할 수 있는 일부 외부 함수 필요
// 1. 외부함수 equals()를 Rect 클래스에 friend로 선언
class Rect { // Rect 클래스 선언
...
friend bool equals(Rect r, Rect s);
};
// 2. RectManager 클래스의 equals() 멤버 함수를 Rect 클래스에 friend로 선언
class Rect {
.............
friend bool RectManager::equals(Rect r, Rect s);
};
// 3. RectManager 클래스의 모든 멤버 함수를 Rect 클래스에 friend로 선언
class Rect {
.............
friend RectManager;
};
Ex) 전역함수를 friend로 선언
#include <iostream>
using namespace std;
class Rect;
bool equals(Rect r, Rect s); // equals() 함수 선언
class Rect { // Rect 클래스 선언
int width, height;
public:
Rect(int width, int height) { this->width = width; this->height = height; }
friend bool equals(Rect r, Rect s); //friend로 선언된 함수는 private 변수에 접근할 수 있다.
};
bool equals(Rect r, Rect s) { // 외부 함수
if (r.width == s.width && r.height == s.height) return true;
else return false;
}
int main() {
Rect a(3, 4), b(4, 5);
if (equals(a, b)) cout << "equal" << endl;
else cout << "not equal" << endl;
}
Ex) 다른 클래스의 멤버 함수를 friend로 선언
#include <iostream>
using namespace std;
class Rect;
class RectManager { // RectManager 클래스 선언
public:
bool equals(Rect r, Rect s);
};
class Rect { // Rect 클래스 선언
int width, height;
public:
Rect(int width, int height) { this->width = width; this->height = height; }
friend bool RectManager::equals(Rect r, Rect s); //RectManager의 equals함수를 프렌드로 선언
};
bool RectManager::equals(Rect r, Rect s) {
if (r.width == s.width && r.height == s.height) return true;
else return false;
}
int main() {
Rect a(3, 4), b(3, 4);
RectManager man;
if (man.equals(a, b)) cout << "equal" << endl;
else cout << "not equal" << endl;
}
Ex) 다른 클래스 전체를 friend로 선언
#include <iostream>
using namespace std;
class Rect;
class RectManager { // RectManager 클래스 선언
public:
bool equals(Rect r, Rect s);
void copy(Rect& dest, Rect& src);
};
class Rect { // Rect 클래스 선언
int width, height;
public:
Rect(int width, int height) { this->width = width; this->height = height; }
friend RectManager; //RectManager 클래스를 friend로 선언
};
bool RectManager::equals(Rect r, Rect s) { // r과 s가 같으면 true 리턴
if (r.width == s.width && r.height == s.height) return true;
else return false;
}
void RectManager::copy(Rect& dest, Rect& src) { // src를 dest에 복사
dest.width = src.width; dest.height = src.height;
}
int main() {
Rect a(3, 4), b(5, 6);
RectManager man;
man.copy(b, a); // a를 b에 복사한다.
if (man.equals(a, b)) cout << "equal" << endl;
else cout << "not equal" << endl;
}
2. 연산자 중복
1) 연산자 중복의 특징
- 본래부터 있던 연산자에 새로운 의미 정의
- C++ 본래 존재하는 연산자만 중복 가능
- 피 연산자 타입이 다른 새로운 연산 정의
- 연산자는 함수 형태로 구현 → 연산자 함수(operator function)
- 반드시 클래스와 관계를 가짐
- 피연산자의 개수를 바꿀 수 없음
- 연산의 우선 순위 변경 X
- 모든 연산자가 중복 가능하지 않음
- 중복 가능한 연산
- 중복 불가능한 연산자
2) 연산자 함수
- 구현 방법
- 클래스의 멤버 함수로 구현
- 외부 함수로 구현하고 클래스에 friend 함수로 선언
- 형식
Ex) 멤버함수로 이항 연산자 중복 구현1: + 연산자 중복
#include <iostream>
using namespace std;
class Power {
int kick;
int punch;
public:
Power(int kick = 0, int punch = 0) {
this->kick = kick; this->punch = punch;
}
void show();
Power operator+(Power op2); // + 연산자 함수 선언
};
void Power::show() {
cout << "kick=" << kick << ',' << "punch=" << punch << endl;
}
Power Power::operator+(Power op2) { // +연산자 멤버 함수 구현
Power tmp; // 임시 객체 생성
tmp.kick = this->kick + op2.kick; // kick 더하기
tmp.punch = this->punch + op2.punch; // punch 더하기
return tmp; // 더한 결과 리턴
}
int main()
{
Power a(3, 5), b(4, 6), c;
c = a + b; // Power 객체 + 연산
a.show();
b.show();
c.show();
}
Ex) 멤버 함수로 이항 연산자 중복 구현2: ==연산자 중복
#include <iostream>
using namespace std;
class Power {
int kick;
int punch;
public:
Power(int kick = 0, int punch = 0) {
this->kick = kick; this->punch = punch;
}
void show();
bool operator==(Power op2); // + 연산자 함수 선언
};
void Power::show() {
cout << "kick=" << kick << ',' << "punch=" << punch << endl;
}
bool Power::operator==(Power op2) {
if (this->kick == op2.kick && this->punch == op2.punch)
return true;
else return false;
}
int main()
{
Power a(3, 5), b(3, 5); // 2 개의 동일한 파워 객체 생성
a.show();
b.show();
if (a == b) cout << "두 파워가 같다." << endl;
else cout << "두 파워가 같지 않다." << endl;
}
3) 멤버 함수로 단항 연산자 중복 구현
- 단항 연산자
- 피연산자가 하나 뿐인 연산자
- 연산자 중복 방식은 이항 연산자의 경우와 거의 유사함
- 단항 연산자 종류
- 전위 연산자(prefix operator)
- !op, ~op, ++op, --op
- 후위 연산자(postfix operator)
- op++, op--
- 전위 연산자(prefix operator)
- 피연산자가 하나 뿐인 연산자
Ex) 멤버 함수로 단항 연산자 중복 구현1 : 전위 ++ 연산자 중복
#include <iostream>
using namespace std;
class Power {
int kick;
int punch;
public:
Power(int kick = 0, int punch = 0) {
this->kick = kick; this->punch = punch;
}
void show();
Power operator++ (); // 전위 ++ 연산자 함수 선언
};
void Power::show() {
cout << "kick=" << kick << ',' << "punch=" << punch << endl;
}
Power Power::operator++() {
kick++;
punch++;
return *this; // 변경된 객체 자신(객체 a) 리턴
}
int main()
{
Power a(3, 5), b;
a.show();
b.show();
b = ++a; // 전위 ++ 연산자 사용
++a;
a.show();
b.show();
}
Ex) 2+a 덧셈을 위한 + 연산자 함수 작성
#include <iostream>
using namespace std;
class Power {
int kick;
int punch;
public:
Power(int kick = 0, int punch = 0) {
this->kick = kick; this->punch = punch;
}
void show();
friend Power operator+(int op1, Power op2); // 프렌드 선언
};
void Power::show() {
cout << "kick=" << kick << ',' << "punch=" << punch << endl;
}
Power operator+(int op1, Power op2) {
Power tmp; // 임시 객체 생성
tmp.kick = op1 + op2.kick; // kick 더하기
tmp.punch = op1 + op2.punch; // punch 더하기
return tmp; // 임시 객체 리턴
}
int main()
{
Power a(3, 5), b;
a.show();
b.show();
b = 2 + a; // 파워 객체 더하기 연산
a.show();
b.show();
}
Ex) a+b를 위한 연산자 함수를 friend로 작성
#include <iostream>
using namespace std;
class Power {
int kick;
int punch;
public:
Power(int kick = 0, int punch = 0) {
this->kick = kick; this->punch = punch;
}
void show();
friend Power operator+(Power op1, Power op2); // 프렌드 선언
};
void Power::show() {
cout << "kick=" << kick << ',' << "punch=" << punch << endl;
}
Power operator+(Power op1, Power op2) {
Power tmp; // 임시 객체 생성
tmp.kick = op1.kick + op2.kick; // kick 더하기
tmp.punch = op1.punch + op2.punch; // punch 더하기
return tmp; // 임시 객체 리턴
}
int main()
{
Power a(3, 5), b(4, 6), c;
c = a + b; // 파워 객체 + 연산
a.show();
b.show();
c.show();
}
'프로그래밍 언어 > C++' 카테고리의 다른 글
11) 가상 함수와 추상 클래스 (0) | 2023.12.09 |
---|---|
10) 상속 (0) | 2023.12.09 |
8) 함수와 참조, 복사생성자 (0) | 2023.12.08 |
7) 여러가지 객체의 생성 방법 (1) | 2023.11.03 |
6) 접근 지정자, static 멤버 (0) | 2023.11.02 |