2009-02-06 2 views
38

가능한 중복 :
When should you use 'friend' in C++?언제 C++에서 친구 클래스를 사용하는

내 C++에 브러시 업 된

(I 자바 개발자입니다) 그리고 내가 friend class 키워드를 건너 왔어요 나는 잠시 잊고 있었다. 이 기능 중 하나가 주방 싱크대의 일부분입니까, 아니면 그냥 바닐라 게터가 아니라 이렇게하는 좋은 이유가 있습니까? 나는 누가 데이터에 액세스 할 수 있는지를 제한한다는 차이점을 이해하지만 이것이 필요할 때 시나리오를 생각할 수는 없다.

참고 : 비슷한 질문을 보았습니다.하지만 구체적으로 말하자면, 코드를보고있는 사람들을 혼란스럽게하는 것 외에는 실제 가치가없는 고급 기능입니다. ?

+0

분명히 친구 클래스에 대한 사용이 있지만, 그렇지 않으면 내가 언어 사양에 포함시키지 않은 것보다 더 큰 마음을 디자인 스타일로 간주하는 경향이 있습니다. 그들은 일반적으로 내 수업 체계를 다시 봐야한다는 것을 나에게 나타내며, 나는 종종 그것을보다 우아하게 재구성하고 친구 클래스의 필요성을 제거 할 수 있음을 발견한다. – Mawg

답변

40

도움이됩니다. 나는 친구 클래스에 대한 가장 일반적인 (합법적 인) 사용이 테스트 일 수 있다고 덧붙였다. 테스터 클래스가 다른 클라이언트 클래스보다 더 많은 액세스 권한을 갖길 원할 수 있습니다. 테스터 클래스는 의도적으로 다른 클래스에서 숨겨져있는 내부 세부 정보를 볼 수있는 좋은 이유가있을 수 있습니다.

+0

좋은 포인트 존 : "친구 클래스에 가장 일반적인 (합법적 인) 사용이 테스트 중일 수 있음을 추가합니다."). – mahesh

+1

중첩 클래스 (펑터, 이터레이터 ...)에 우정을 부여하는 것은 내가 '친구'를 사용하는 가장 일반적인 방법입니다. 관련 클래스에 대한 액세스 권한 부여는주의 깊게 진행되어야하며 (이는 단단한 결합을 의미 함) 정당화 될 수 있습니다. 나는 두 번째 테스트도했다. –

19

내 경험에 따르면 캡슐화를 중단하는 데 사용 된 빈도와 비교하여 실제로 데이터 캡슐화를 향상시키는 친구 (또는 약간 비슷합니다)가 드문 사례입니다.

거의 유용하지 않지만 이전에 단일 클래스였던 클래스를 몇 가지 공통 데이터/기능에 액세스해야하는 두 개의 별도 클래스로 분할해야하는 경우에 사용합니다.

Outlaw 프로그래머의 의견에 응답하려면 편집 : 우리는 이것에 절대적으로 동의합니다. 클래스를 분리 한 후에 friend'ing 클래스를 제외하고 다른 옵션은 public 접근자를 만드는 것입니다. 어떤 사람들은 우호적 인 클래스가 어떻게 든 캡슐화를 깨뜨린다고 생각합니다. 왜냐하면 부적절하게 많이 사용되는 것을 보았 기 때문에 많은 사람들이 코드가 올바르게 사용 된 코드를 보지 못했을 것입니다. 드문 일이기 때문입니다. 나는 그것을 말하는 당신의 방법을 좋아합니다 - 친근감은 당신이 당신의 수업을 나누지 못하게하고 모든 사람들이 대중들에게 접근 가능하게하는 것 사이의 좋은 중간 단계입니다.

David Thornley에 대한 응답 편집 : C++에서 이와 같은 작업을 수행 할 수있는 유연성은 C++에 대한 설계 결정 결과입니다. 이것이 유연한 언어에서 일반적으로 좋은 스타일과 나쁜 스타일을 이해하는 것이 무엇보다 중요하다고 생각합니다. Java의 관점은 이러한 클래스가 제공되지 않도록 친구 클래스를 사용해서는 안되지만 C++ 프로그래머는 매우 융통성 있지만 때로는 잘못 사용 된 언어 구문을 적절히 사용하도록 정의하는 것이 커뮤니티의 책임이라는 점입니다.

톰에 대응하기 위해 편집 : 변경은 반드시 캡슐화를 깨뜨리는 것은 아니지만 캡슐화를 위반하는 사람들을 보는 것이 훨씬 일반적이기 때문에 실제 상황에서 본 가변 키워드의 많은 용도가 캡슐화를 중단합니다. 처음에는 mutable의 적절한 사용을 실제로 발견하고 이해하는 것보다 가변적이다.

+3

+1 때때로 가독성 문제와 관련하여 기존 클래스에서 새 클래스를 추출해야 할 수도 있지만 여전히 단단한 결합을 유지하려고합니다. 새로운 클래스에 특별한 액세스 권한을 부여하고 싶지만 이러한 메소드를 public으로 만들고 싶지는 않습니다. –

+3

C++ 철학은 날카 롭고 강력한 도구를 제공하고 잘못 사용되는 방법에 대해 걱정하지 않는 것을 명심하십시오. Stroustrup은 "Design & Evolution"어딘가에서 이것을 설명합니다. 이것이 바로 "친구"가 C++이며 Java (다른 철학을 가짐)가 아닌 이유입니다. –

+7

'mutable'은 캡슐화를 깨뜨리는 이유는 무엇입니까? – Tom

1

드물게 사용되어야하는 언어 기능 중 하나 인 friend 구조를 보지만 유용하지는 않습니다. friend 클래스를 만들기위한 몇 가지 패턴이 있으며, 그 중 많은 클래스가 이미이 사이트의 오른쪽에있는 "관련"막대에 있습니다. ====>

+0

멋진 댓글이지만 거의 대답이 없음 – Mawg

4

내가 현명하게 사용하면 친구 키워드 캡슐을 향상시킬 수 있다고 의견에 동의 Memento design pattern

1

우정은 동일한 추상화 또는 인터페이스를 제공하기 위해 함께 작동하는 여러 클래스 및/또는 기능이있는 경우에 사용됩니다. 고전적인 예제는 어떤 종류의 수치 클래스를 구현하고 있으며, 모든 비 멤버 연산자 함수 (*, -, +, < < 등)는 우정을 맺어 수치 클래스의 개인 데이터를 처리 할 수 ​​있습니다.

이러한 사용 사례는 다소 드물지만 존재하지만 친구가 매우 유용합니다.

+0

질문은 다른 친구의 용도가 아닌 친구 수업에 관한 것이 었습니까? –

+1

같은 생각입니다. 그들이 일하는 추상화를 제공하기 위해 함께 일한다면 당신은 기능이나 수업에 우정을 나누게됩니다. –

7

구체적인 인스턴스는 하나의 클래스가 다른 팩토리 클래스를 통해서만 만들어 지도록하는 클래스 팩토리이므로 생성자를 비공개로 만들고 팩토리 클래스를 생성 된 클래스의 친구로 만듭니다.

2 "12- 포인트 3/4"드라이브 소켓과 비슷하지만 꼭 필요한 것은 아니지만 필요할 때 정말 기쁩니다. 친구에 대한

+2

이것은 좋은 지적입니다. C++에는 패키지 (C# 또는 Java로 팩토리를 구현하는 한 가지 방법 일 수 있음)가 없으므로 친구 팩토리를 사용하거나 보호 된 생성자와 생성 된 자식 구현 클래스가 있어야합니다. 공장. 친구는 C++에서 코드가 적은 팩토리를 가질 수 있습니다. –

2

자주 제기되는 질문 (FAQ)의 섹션 : 친구에 대한 here

FQA의 섹션 : 친구에 대한보기의 here

두 개의 서로 다른 점.

12

하나의 클래스 (출고시)가 다른 클래스 (유형)의 인스턴스를 생성하는 것을 원할 때. Type의 생성자를 private로 만들 수 있으므로 Factory 만 Type 객체를 만들 수 있습니다. 유효성 검사기 역할을 할 수있는 다른 클래스에 수표를 위임 할 때 유용합니다. 한 가지 사용 시나리오.

P. C#에서 "친구"키워드가 실제로 누락되었습니다. ...

0

나는 개인용 방법을 테스트하는 장치로 항상 친구를 사용합니다. 이 작업을 수행하는 다른 방법은 공용 인터페이스를 많은 테스트 메소드로로드하는 것인데, 이는 너무 혼란스럽고 별도의 테스트 클래스에서 테스트 메소드를 숨기는 것을 선호합니다. 이 같은

뭔가 :

class cMyClassTest; 

class cMyClass 
{ 
public: 
..... 

private: 
friend cMyClassTest; 
int calc();  // tricky algorithm, test carefully 

}; 

class cMyClassTest 
{ 
public: 
int test_calc() 
{ 
    cMyClass test; 
    .... 
    int result = test.calc(); 

    if(result == 42) 
     return 1; 
    return 0; 
} 
}; 
0

친구 클래스는 우리 모두가 주로 그래서 우리는 필요가 다른 값을 반환하지하는 데 사용하는 값을 사용 그래서 다른 클래스의 변수의 값 acesss 알고 의미 클래스를 메인 함수로 변환 한 다음 필요한 클래스 멤버 함수를 메인으로하지만 클래스라는 문제가 다른 클래스의 친구라면 친구 클래스가 그 클래스의 아래에 있어야합니다.

1

다음은 몇 가지 예입니다. 친구 클래스는 캡슐화의 이유를 무시하지 않고 합법적으로 사용할 수 있습니다.

MyClass는 GeneralClass에서 상속됩니다. MyClass가 커 졌으므로 HelperClass를 만들어 MyClass의 일부 기능을 캡슐화했습니다. 그러나 HelperClass는 GeneralClass의 일부 보호 된 기능에 액세스하여 해당 기능을 제대로 수행해야하므로 HelperClass를 MyClass의 친구로 만들 수 있습니다.

이 기능은 모든 사람이 사용할 필요가 없으므로 보호 기능을 제공하는 것보다 낫지 만 코드를 OOP 방식으로 구성하여 MyClass가 너무 복잡해지지 않게하는 데 도움이됩니다. HelperClass가 상속에 의해 MyClass와 구체적으로 관련되어 있지는 않지만 코드와 디자인에 구체화 된 일종의 논리적 인 연결을 "친구"로 가지고 있기 때문에 의미가 있습니다.

관련 문제