updated... 2024/09/07
C++에서 "friend" 키워드는 클래스의 멤버 함수나 전체 클래스를 다른 클래스에 "친구"로 지정하여 해당 클래스의 private 멤버나 protected 멤버에 접근할 수 있도록 허용하는 기능을 제공합니다.
다음은 friend 키워드의 핵심 개념들입니다:
1. **Friend 함수**:
- 특정 클래스의 멤버 함수가 아니지만, 해당 클래스의 private 또는 protected 멤버에 접근할 수 있는 함수입니다.
- friend 키워드를 사용하여 클래스 정의 내에서 선언됩니다.
```cpp
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// Friend 함수 선언
friend void showSecretValue(MyClass &obj);
};
void showSecretValue(MyClass &obj) {
// Friend 함수이므로 private 멤버에 접근 가능
std::cout << "Secret Value: " << obj.secretValue << std::endl;
}
```
2. **Friend 클래스**:
- 한 클래스가 다른 클래스에 대해 friend로 선언되면 friend로 선언된 클래스의 모든 멤버 함수는 해당 클래스의 private 및 protected 멤버에 접근할 수 있습니다.
```cpp
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// Friend 클래스 선언
friend class FriendClass;
};
class FriendClass {
public:
void accessSecretValue(MyClass &obj) {
// Friend 클래스이므로 MyClass의 private 멤버에 접근 가능
std::cout << "Accessing Secret Value: " << obj.secretValue << std::endl;
}
};
```
3. **Friendship은 대칭적이지 않고 전이적이지 않다**:
- 만약 클래스 A가 클래스 B의 friend로 선언되었다고 해서 B가 A의 friend가 되는 것은 아닙니다.
- 또한, A가 B의 friend이고 B가 C의 friend라고 해서 A가 C의 friend가 되는 것도 아닙니다.
Friend 키워드는 주로 클래스의 중요한 내부 상태를 특수한 함수나 클래스에서만 접근할 수 있도록 필요할 때 사용됩니다. 그러나 남용하면 클래스의 캡슐화(encapsulation)를 저해할 수 있으므로 신중하게 사용해야 합니다.
다음은 `friend` 키워드를 사용하는 몇 가지 예제입니다:
### Friend 함수 예제
```cpp
#include <iostream>
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// friend 함수 선언
friend void showSecretValue(MyClass &obj);
};
void showSecretValue(MyClass &obj) {
// friend 함수이므로 private 멤버에 접근 가능
std::cout << "Secret Value: " << obj.secretValue << std::endl;
}
int main() {
MyClass obj(42);
showSecretValue(obj); // Secret Value: 42 출력
return 0;
}
```
### Friend 클래스 예제
```cpp
#include <iostream>
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// friend 클래스 선언
friend class FriendClass;
};
class FriendClass {
public:
void accessSecretValue(MyClass &obj) {
// friend 클래스이므로 MyClass의 private 멤버에 접근 가능
std::cout << "Accessing Secret Value: " << obj.secretValue << std::endl;
}
};
int main() {
MyClass obj(42);
FriendClass f;
f.accessSecretValue(obj); // Accessing Secret Value: 42 출력
return 0;
}
```
### Friend 멤버 함수 예제
간단하게 하려면 `friend` 함수를 클래스 내부에서 간단히 선언할 수도 있습니다.
```cpp
#include <iostream>
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// friend 함수 선언
friend void MyClassFriendFunction(MyClass &obj) {
std::cout << "Secret Value from friend function: " << obj.secretValue << std::endl;
}
};
int main() {
MyClass obj(42);
MyClassFriendFunction(obj); // Secret Value from friend function: 42 출력
return 0;
}
```
이 예제들은 `friend` 키워드를 사용하여 어떻게 클래스의 private 멤버에 접근할 수 있는지 보여줍니다. `friend` 키워드는 신중하게 사용해야 하며, 클래스의 캡슐화 원칙을 저해하지 않도록 주의해야 합니다.
## java 에서의 구현 ##
java에서는 friend 함수가 없다.
public class MyClass {
// private 필드
private int secretValue;
// 생성자
public MyClass(int value) {
this.secretValue = value;
}
// MyClass의 private 멤버를 외부에서 접근할 수 있도록 getter를 제공
int getSecretValue() {
return this.secretValue;
}
}
// 이 클래스는 MyClass의 secretValue에 접근할 수 있음
public class FriendClass {
public void showSecretValue(MyClass obj) {
// getSecretValue() 메서드를 통해 private 멤버에 접근 가능
System.out.println("Secret Value: " + obj.getSecretValue());
}
}
public class Main {
public static void main(String[] args) {
MyClass obj = new MyClass(42);
FriendClass friendObj = new FriendClass();
friendObj.showSecretValue(obj); // Secret Value: 42 출력
}
}
getter, setter로 구현.
### C++에서의 접근 제어
C++에서 클래스 메서드들이 자신의 private 멤버에 접근할 수 있는 것은 기본적인 동작입니다. 이는 클래스 내부의 모든 메서드가 해당 클래스의 다른 멤버들에 자유롭게 접근할 수 있도록 함으로써, 데이터 캡슐화(encapsulation)를 유연하게 구현할 수 있게 합니다.
#### 예제:
```cpp
#include <iostream>
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// Public 메서드가 private 멤버에 접근
void showSecretValue() const {
std::cout << "Secret Value: " << secretValue << std::endl;
}
};
int main() {
MyClass obj(42);
obj.showSecretValue(); // Secret Value: 42 출력
return 0;
}
```
### Friend 함수와 Friend 클래스
C++에서 `friend` 키워드는 클래스의 엄격한 접근 제어를 우회할 수 있도록 설계되었습니다. 이는 특정 함수나 클래스가 다른 클래스의 private 멤버들에 접근할 수 있도록 허용하는 유용한 기능입니다.
#### Friend 함수 예제:
```cpp
#include <iostream>
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// Friend 함수 선언
friend void showSecretValue(MyClass &obj);
};
void showSecretValue(MyClass &obj) {
std::cout << "Secret Value: " << obj.secretValue << std::endl;
}
int main() {
MyClass obj(42);
showSecretValue(obj); // Secret Value: 42 출력
return 0;
}
```
#### Friend 클래스 예제:
```cpp
#include <iostream>
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// Friend 클래스 선언
friend class FriendClass;
};
class FriendClass {
public:
void accessSecretValue(MyClass &obj) {
std::cout << "Accessing Secret Value: " << obj.secretValue << std::endl;
}
};
int main() {
MyClass obj(42);
FriendClass f;
f.accessSecretValue(obj); // Accessing Secret Value: 42 출력
return 0;
}
```
### 요약
- **Public 메서드**: 클래스 내부의 public 메서드는 기본적으로 자신의 클래스에서 정의된 private 멤버나 protected 멤버에 접근할 수 있습니다.
- **Friend 함수**: 특정 클래스의 멤버가 아니지만, 해당 클래스의 private 및 protected 멤버에 접근할 수 있도록 선언된 함수입니다.
- **Friend 클래스**: 다른 클래스의 모든 메서드가 해당 클래스의 private 및 protected 멤버에 접근할 수 있도록 허용된 클래스입니다.
friend 클래스/함수의 기능은 상속이 아닌 관계에서 다른 클래스의 private멤버에 접근하는 방식이라 어떤 경우 꽤 유용하고, 캡슐화도 본래 class가 선택할 수 있는 부분이라 캡슐화를 깼다고 하기도 애매하다. 그러나 왜 굳이 friend를 만들었나 하면... friend 함수의 경우 class 정의인 {} 밖에 쓰기 좋다. 혼자서 대부분의 프로그램을 짜다 보면 아는 기술을 단순한 목적으로 쓰기 마련이다.
여기에 대한 chatGPT-4o의 답변은...
네, 맞습니다! `friend` 함수는 클래스 선언 내부에서 함수의 원형(prototype)을 선언하고, 실제 함수 정의는 클래스 선언 외부에 위치시킴으로써 클래스 선언을 깔끔하게 유지할 수 있습니다. 이는 특히 클래스가 매우 클 때 유용합니다.
### Friend 함수 정의의 기본 구조
1. 클래스 선언 내에 `friend` 함수의 원형(prototype)을 선언
2. 클래스 외부에서 실제 `friend` 함수의 정의를 작성
아래 예제는 이러한 구조를 잘 보여줍니다.
#### 클래스 내부에 `friend` 함수 원형 선언
```cpp
#include <iostream>
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// friend 함수 원형 선언
friend void showSecretValue(MyClass &obj);
};
```
#### 클래스 외부에 `friend` 함수 정의
```cpp
// 클래스 외부에서 friend 함수 정의
void showSecretValue(MyClass &obj) {
std::cout << "Secret Value: " << obj.secretValue << std::endl;
}
int main() {
MyClass obj(42);
showSecretValue(obj); // Secret Value: 42 출력
return 0;
}
```
### 자세한 설명
1. **클래스 선언 내부**:
클래스 선언 내부에서는 `friend` 함수의 원형만 선언합니다. 이렇게 하면 클래스의 인터페이스가 깔끔하게 유지됩니다.
2. **클래스 선언 외부**:
함수의 실제 정의는 클래스 선언 외부에 위치시키므로 클래스 자체가 너무 커지지 않도록 합니다. 이렇게 하면 코드 가독성이 높아지고 유지보수가 쉬워집니다.
3. **컴파일러와의 호환성**:
컴파일러는 `friend` 함수가 특정 클래스의 private 및 protected 멤버에 접근할 수 있다는 것을 인식하여, 클래스 외부에 정의된 함수도 클래스의 내부 상태를 조작할 수 있게 허용합니다.
```cpp
#include <iostream>
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// friend 함수 원형 선언
friend void showSecretValue(MyClass &obj);
// 다른 함수 예시 (멤버 함수)
void display() const {
std::cout << "Display Secret Value: " << secretValue << std::endl;
}
};
// 클래스 외부에서 friend 함수 정의
void showSecretValue(MyClass &obj) {
std::cout << "Secret Value: " << obj.secretValue << std::endl;
}
int main() {
MyClass obj(42);
showSecretValue(obj); // Secret Value: 42 출력
obj.display(); // Display Secret Value: 42 출력
return 0;
}
```
위 예제에서는 다음과 같은 이점을 얻을 수 있습니다:
- 클래스 선언 부분은 함수 원형(prototype)만 포함하여 깔끔하게 유지됩니다.
- 실제 함수 정의는 클래스 선언 외부로 이동하여 코드 가독성과 유지보수성을 향상시킵니다.
- friend 함수는 클래스의 private 멤버에 접근할 수 있어 필요시 내부 데이터 조작이 가능합니다.
이를 통해 클래스 선언을 간소화하고, 기능적인 코드를 외부로 분리함으로써, 구조적이고 유지보수 가능한 코드를 작성할 수 있습니다.
사실 friend는 안써도 된다. 그러나 C++은 JAVA처럼 refactoring이 완벽하지 않으므로 코딩 편의상 알고 있는 것은 괜찮다.
실제로 대부분의 경우에는 클래스의 캡슐화 원칙을 유지하면서도 다른 방법으로 요구사항을 충족시킬 수 있습니다. `friend` 함수를 굳이 사용하지 않아도 되도록 대체할 수 있는 몇 가지 방법을 소개하겠습니다.
### Alternatives to `friend` Functions
1. **Public Getter 및 Setter 함수**:
- 클래스의 private 멤버에 접근하기 위한 메서드를 제공하여 외부에서 필요한 정보를 얻을 수 있도록 합니다.
```cpp
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
// Getter
int getSecretValue() const {
return secretValue;
}
// Setter
void setSecretValue(int value) {
secretValue = value;
}
};
int main() {
MyClass obj(42);
std::cout << "Secret Value: " << obj.getSecretValue() << std::endl;
return 0;
}
```
2. **접근자를 통한 접근 (Accessor)**:
- 멤버 함수 또는 외부 함수를 통해 클래스 멤버에 접근하도록 클래스를 설계합니다.
```cpp
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
void showSecretValue() const {
std::cout << "Secret Value: " << secretValue << std::endl;
}
};
int main() {
MyClass obj(42);
obj.showSecretValue(); // Secret Value: 42 출력
return 0;
}
```
3. **프록시(Proxy) 클래스 또는 래퍼(Wrapper) 클래스**:
- 원래 클래스의 인터페이스를 캡슐화하여 private 멤버에 대한 접근을 특정 함수나 클래스에서만 허용하도록 할 수 있습니다.
```cpp
class MyClass {
private:
int secretValue;
public:
MyClass(int value) : secretValue(value) {}
friend class Accessor;
};
class Accessor {
public:
static int getSecretValue(const MyClass &obj) {
return obj.secretValue;
}
};
int main() {
MyClass obj(42);
std::cout << "Secret Value: " << Accessor::getSecretValue(obj) << std::endl;
return 0;
}
```
### When to Use `friend` Functions
- **퍼포먼스 최적화**: 경우에 따라 성능을 최적화하기 위해 `friend` 함수를 사용할 수 있습니다. 예를 들어, private 멤버 변수에 직접 접근하여 불필요한 함수 호출을 줄일 때.
- **특별한 인터페이스 디자인**: 두 클래스가 아주 밀접하게 연관되어 있어 이들 간의 엄격한 캡슐화가 필요하지 않은 경우.
- **테스트 및 디버깅 편의를 위해**: 테스트 코드에서 private 멤버에 접근하여 상태를 검사하거나 변경하는 경우.
그러나 `friend` 함수가 캡슐화(encapsulation)를 저해할 수 있으므로, 사용 시 주의를 기울여야 합니다. 일반적으로 `friend` 함수를 사용할 때마다 그 목적과 필요성을 명확히 이해하고 사용하는 것이 중요합니다.
결론적으로 `friend` 함수를 반드시 사용할 필요는 없으며, 가능한 경우 다른 대체 방법을 사용하는 것이 더 좋은 설계가 될 수 있습니다. 이를 통해 클래스의 데이터 숨김(data hiding) 원칙을 유지하고, 더 나은 모듈화와 유지보수성을 확보할 수 있습니다.
연봉 정보를 알기 위한 유튜브에서의 행동 기록
구글의 AI는 뛰어나다. 물론, IBM 다음으로.
그 이유는 바둑 대결 같은 show는 이미 오래 전 퀴즈, 체스 분야에서 했고 이미 의료 진료에서 상용화를 이루어 국내 병원에 판매하고 있는 IBM
그러나 분야는 다르기에 동영상 추천 분야는 넷플릿스보다 구글이 뛰어나다고 느낀다. 정량적이지 않아 미안하지만 한 명의 유저로서.
솔직한 유튜버들의 수입 정보를 보다보면, 이 후 구글이 계속 추천해 준다.
치과의사 - https://www.youtube.com/watch?v=P_eZysqKK3A, 대졸직후 월200~300, 전문의 일당 50, 20일-1000, 교정 일당 80, 월 1600~2000, 지방급여가 더 많음, 기타 좋은 이야기 [구독각]
당구장 사장 - https://www.youtube.com/watch?v=FgsaC_5qlrE&t=43s , 한달 3000이상 번 기억. 솔직하고 개그 프로만큼 재밌음 계속 보게됨
IT 영업 - https://www.youtube.com/watch?v=dX7JrFmdg0o 490~970
철구 - https://www.youtube.com/watch?v=LLz8J-XsMEQ 아프리카 210~400, 유투브 3100,
킴성태 - https://www.youtube.com/watch?v=2zU8q-2Q4C4 140~740 연봉 6000
실리콘 벨리 - https://www.youtube.com/watch?v=9vrrNGEj2_k 연봉 2억 가능
'C++' 카테고리의 다른 글
Python과 C++을 연결하는 방법 (0) | 2019.01.26 |
---|---|
COM(Component Object Model) 개요 및 python 통합 고려. (6) | 2019.01.06 |
`constexpr`을 전체 코드에 일괄적으로 적용하는 것은 현실적이지 않을 수 있지만, (0) | 2019.01.06 |
Unreal Engine 플러그인에서 `constexpr`를 사용 (0) | 2019.01.03 |
기존 라이브러리에 `constexpr`을 도입 (0) | 2019.01.02 |
최근댓글