2016-08-01 4 views
3

클래스 A는 클래스 B 인스턴스의 컨테이너입니다.클래스 A에서 친구로 선언 된 함수가 클래스 B에서 공용 함수로 정의되어야하는 이유는 무엇입니까?

파일 아 :

#include "B.h" 

Class A 
{ public: 
    unique_ptr<B>      getInstanceOfB(); 

    private: 
    unique_ptr<map<int, shared_ptr<B>>> uptr_BInstancesMap; 
    map<string, int>     map__BUniqueValues; 

    friend int       B::getValueIndex(const string); 
}; 

파일 BH :

Class B 
{ public: 
    unique_ptr<B>      returnInstanceOfB(); 
// int         getValueIndex(const string); // Compiles fine 

    private: 
    int         int__ValueIndex; 
    int         getValueIndex(const string); // "error: 'int B::getValueIndex(std::string)' is private" 
} 

(A)의 인스턴스에 저장된 B 10 만 개 인스턴스의 위쪽이있을 수 있지만,로 표현 훨씬 적은 수의 고유 값이있을 것 B의 인스턴스 B. 그래서 A의 인스턴스에 고유 한 값을 저장하고 인덱스를 B의 각 인스턴스에서 (공유) 값에 저장하는 것이 좋습니다. 친구 기능에 대해 합리적인 시나리오처럼 보입니다.

getValueIndex()는 내에서 범위 내에서 사용됩니다. 공개되어서는 안됩니다. friend 함수 정의가 개인용이 될 수없는 이유를 설명하는 사람 (위험한 예가있을 수 있음)이 있습니까?

+0

@ 마크 랜섬 : 잘못된 표현. "클래스 A는 클래스 B의 컨테이너입니다"가 더 정확합니까? – pbyhistorian

+0

훨씬 좋습니다. 내 의견을 지금 삭제하겠습니다. –

+0

클래스 A에서'friend int B :: getValueIndex (const string);을 선언하면 클래스 A의 개인/보호 된 멤버에 액세스 할 수있게됩니다. – Dmitri

답변

2

"원형도"가 있습니다.

A의 friend는 선언 된 함수가 개인 부분에 액세스 할 수 있음을 의미합니다.

그러나이 선언에 액세스하려면 A 자체에 액세스 할 수 있어야하므로 B는 A를 친구로 가져야합니다.

"순결"에 대한 귀하의 소원을 이해하지만 C++은 "순수한"언어 이외의 것입니다. A와 B가 밀접하게 관련되어 있고 두 사람 모두에게 책임이있는 경우 단일 선언으로 미친 대신에 서로 친구가되게하십시오.

위험한 일을 할 수있는 사람이 아무도 없으며 이미 위험 영역을 소유하고 있습니다. 이미 알고 있습니다 ... 그렇다면 합병증은 왜 발생합니까?

+0

"친구 클래스 A"를 B 클래스에 추가하면 트릭을 만들었습니다! 나는 아직 "그 선언문에 접근하기 위해서는 A 자체에 접근 할 수 있어야한다."그러나 이것이 나의 추측이다 : A 클래스의 friend 함수 선언은 A가 B :: getValueIndex() 접근 권한을주고 싶다고 컴파일러에게 알린다. B :: getValueIndex()는 private이기 때문에 컴파일러는 거부합니다. A는 거기에 있다는 것을 알지도 못합니다. B 클래스에 "친구 클래스 A"를 추가하면 B :: getValueIndex()를 포함하여 B의 private 멤버에 액세스 할 수있게되어 컴파일러가이 함수에 A의 private 멤버에 대한 액세스 권한을 부여 할 수 있습니다. – pbyhistorian

+0

정확히 : 비공개로 요구되는 이중 "혜택을 가진 친구"... ;-) –

0

은에 걸릴 내 :

개인 방법은 클래스의 외부 영향을주지 않고, 마음대로 변경해야합니다. B의 개인 메서드를 A의 친구로 만들면 해당 개인 메서드의 서명 서명을 변경하지 않고 변경할 수 없습니다 A.

+0

Arkadiy : A의 개인 회원을 변경 (예 : 이름 바꾸기) 한 경우 B의 친구 기능을 변경해야합니다. 친구 기능을 사용하면 암기 적으로 두 클래스를 모두 변경해야한다는 사실이 인정됩니다. – pbyhistorian

+0

아무도 다른 사람없이 "친구"가 될 수 있습니다. –

+0

에밀리오 : 당신의 요점을 잘 모르겠습니다. 당신은 정교 할 수 있습니까? – pbyhistorian