들어가면서
클래스를 공부하다보면 심화 개념으로 friend 키워드를 공부해야하는 상황이 있다.
오늘은 간단하게 friend 키워드의 개념과 특징을 살펴보도록 하자.
friend 키워드란?
경우에 따라서 클래스간 멤버를 공유해야하는 상황이 생기기도 한다.
이때, friend 키워드를 사용하면 클래스간 멤버를 접근하고 공유할 수 있게 된다.
말 그대로 friend 키워드는 클래스간 친구를 할 수 있게 되어서 private에 정의된 멤버도 접근할 수 있게 된다.
friend 키워드의 특징
클래스 내부에서 friend 키워드를 멤버 함수에 사용하면 해당 멤버 함수는 멤버함수가 아닌 외부 함수로 인식된다.
따라서, 해당 함수는 비클래스 범위로 내보내져서 객체 생성(객체 인스턴스)과 무관하게 존재하며 호출 될 수가 있다.
('friend 함수를 원래는 클래스와 연관없는 외부함수인데, friend에 의해 클래스에 접근이 가능하다.'라고 받아들여도 좋다.)
더불어서, friend 키워드를 멤버 함수가 아닌 class에도 사용할 수 있게 되는데, 이는 사용된 클래스에서 friend가 있는 클래스의 멤버에 접근할 수 있게 된다.
또한, 해당 클래스의 접근 제어 지시자의 영향을 받지 않는다.
그러므로, 해당 함수는 해당 클래스의 private의 멤버 변수나 함수에 접근이 가능해진다.
(※private은 클래스 내부에서만 직접 읽고 쓰기가 가능하다. 외부에서 접근하려면 public을 통해 간접적으로 접근해야한다.)
이는, 캡슐화를 무시하게 되지만, 수평적인 관계의 클래스간 멤버를 접근할 수 있어 상황에 따라 사용되기도 한다.
클래스 캡슐화가 무시되므로 코드의 유지보수가 어려워질 수 있으므로 신중히 friend 키워드를 사용해야한다.
friend 키워드를 사용한 예제 | friend 함수
#include <iostream>
#include <string>
using namespace std;
class Tmp{
private:
string _name;
public:
Tmp(string name)
: _name { name } {}
friend void accessTmp(Tmp& obj);
};
void accessTmp(Tmp& obj) {
obj._name = "John";
cout << "The name of obj is changed from noname to " << obj._name << "." << endl;
}
int main() {
Tmp t {"noname"};
accessTmp(t);
return 0;
}
위 예제는 Tmp 클래스 내부에 선언된 friend 함수 accessTmp가 존재한다.
accessTmp 함수는 클래스 외부에서 정의되며, Tmp 객체 생성과 무관하게 존재하게 된다.
main()함수에서 t객체가 생성되고 accessTmp에 의해 Tmp 클래스의 private에 접근할 수 있게 된다.
friend 키워드를 사용한 예제 | friend 클래스
#include <iostream>
#include <string>
using namespace std;
class Friend;
class Tmp{
private:
string _name;
public:
Tmp(string name)
: _name { name } {}
friend class Friend;
string getName() const { return _name; }
};
class Friend {
public:
void accessTmp(Tmp& obj) {
obj._name = "John";
cout << "The name of obj is changed from noname to " << obj._name << "." << endl;
}
};
int main() {
//Tmp 객체 t를 선언하고 _name인 noname을 출력합니다.
Tmp t {"noname"};
cout << "The name of t is " <<t.getName() << "." <<endl; //The name of t is noname.
//Friend 객체 f를 선언합니다. 이때, Friend 클래스는 Tmp 클래스의 친구라서 Tmp 멤버에 접근할 수 있게 됩니다.
Friend f;
//Tmp 친구인 Friend의 멤버함수에 의해 Tmp의 멤버 변수인 _name에 접근하고 수정합니다.
//이때, _name은 noname에서 John으로 변경됩니다.
f.accessTmp(t);
//변경된 _name인 John을 출력합니다.
cout << "The name of t is " <<t.getName() << "." <<endl; //The name of t is John.
return 0;
}
'C++' 카테고리의 다른 글
C++ : 클래스 내부의 this 포인터의 역할(this->멤버/(*this).멤버) (0) | 2024.03.20 |
---|---|
C++ : 변환생성자(conversion constructor)란? (매개변수 생성자와의 차이점은?) (0) | 2024.03.20 |
C++ : cin >> int배열;은 왜 불가능 할까? (0) | 2024.03.15 |
C++ : 정적 멤버변수와 정적 멤버함수란? (Class심화) (0) | 2024.01.02 |
C++ : 정적 지역변수(static local variable)란? (0) | 2023.12.31 |