https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms
Idioms라는 용어가 생소하다. 한국어로 하면 관용구인데, 개발 용어로는 그냥 관용구라고 생각하면 안될 것 같아서 서문을 살짝 읽어봤다.
Idiom라는 것은 C++를 사용하여 프로그래밍하거나 설계할 때 자주 사용하게 되는, 재사용 가능한 패턴이나 팁이다. 특정 상황에서 쓰이는, 특정 상황에 대처하기 위한 일반적인 관행이라는 뜻이다.
이 목록은 이런 관용구들을 모아둔 리스트이다. 이 관용구들을 이해함으로써 다른 사람의 코드가 왜 그렇게 짜였는지 읽기 쉬워지고, 언어가 어떤 특성을 가져서 어떻게 짜면 좋은지 등등을 이해할 수가 있다.
이 목록들은 각각 Idiom의 Intent, Also Known As(Alias), Motivation, Solution and Sample Code, Known Uses, Related Idioms, References를 설명한다. 양식이 그렇게 되어있다. 나도 맞춰서 정리하겠다.
동아리 세미나 과제인데, 빨갛게 안 만들어진 페이지빼고 공부한다.
클래스의 세부 구현에 접근하는 권한을 어떻게 나눌지를 컨트롤 한다.
C++에는 friend라는 예외적인 키워드를 제공한다. public이나 private을 무시하고 friend라고 선언된 대상에게는 public으로 동작한다. friend 선언은 한 클래스 내부에 완벽히 접근할 수 있도록 해준다.
class Foo
{
private:
void A(int a);
void B(float b);
void C(double c);
friend class Bar;
};
class Bar {
// This class needs access to Foo::A and Foo::B only.
// C++ friendship rules, however, give access to all the private members of Foo.
};
예시를 보면 Foo class에서 Bar class를 friend라고 설정했기 때문에 Bar class는 Foo의 모든 private한 변수들에 접근이 가능하다. 그러나 주석을 보니 A와 B의 접근만 Foo에게 풀고 싶었던 모양이다. 그런데 Friend는 그런 기능을 제공하지 않는다. 모두 public으로 풀어버리거나, 풀지 않거나. 이 선택지 뿐이다. 게다가 이는 두 클래스간의 coupling(의존도가 생기는 것, 한 클래스를 바꾸면 다른 클래스도 바꿔야하는것)을 늘리는 방향으로 가게 된다.
남은 private 맴버들이 클라이언트 코드를 깨지 않고 인터페이스가 바뀔 수 있게 하기 위해, 일부 멤버들에게 선택적으로 접근 권한을 주는 것이 필요하다. 그래야 둘 사이의 coupling을 줄어든다. 이를 위해 쓰는 것이 Attorney-Client idioms.
Attorney-Client는 간접적인 접근 레벨을 추가하는 것이다. 그래서 변호사라는 단어를 쓰나? 세부 사항에 대한 접근 권한을 컨트롤하기 위해, 클라이언트의 변호사가 되어줄 클래스를 만든다. 변호사 클래스를 통해 접근하게 한 번 걸러주는 것이다. 변호사 클래스는 클라이언트가 제공하는 인터페이스의 일부만을 복제한다.
class Client
{
private:
void A(int a);
void B(float b);
void C(double c);
friend class Attorney;
};
class Attorney {
private:
static void callA(Client & c, int a) {
c.A(a);
}
static void callB(Client & c, float b) {
c.B(b);
}
friend class Bar;
};
class Bar {
// Bar now has access to only Client::A and Client::B through the Attorney.
};
이러면 Foo class가 Attorney class를 통해 Client의 A와 B에만 접근할 수 있게 된다.
Attorney class는 함수의 전체 세트에 접근하는 걸 제한한다. 모든 Attorney class의 메소드는 inline static이며, 각자가 Client 인스턴트를 참조하며 함수 호출을을 전달해준다. friend로 자신(Attorney)에 접근할 클래스, 멤버 함수, free 함수들을 결정한다.
Client class를 모두 private 멤버로 구현한 채 Attorney class를 사용하면 예상치 못한 클래스가 Client 전체에 접근하는 것을 막아준다. Attorney를 다양한 셋으로 여러 개 만들어 쓸 수도 있다.
그러다보면 클래스(Client에 해당하는)를 상속받아 써야하는 경우는 충분히 생각해볼 수 있다. 그런데 C++에서 friend를 계층적으로 상속할 수 없다. 그럼 Attorney는 어떻게 상속한 클래스에 접근 권한을 주지? 상속 받은 클래스가 원래 클래스의 가상의 함수를 override하면 base의 private 가상 함수에 접근이 가능하다.
아래는 Attorney-Client를 쓴 예제인데, Derived::Func은 main이 Derived의 friend가 아닌데도 불러낼 수가 있다. Drived Class의 세부 구현에 접근하기 위해서 똑같은 idiom을 적용했다.
#include <iostream>
class Base {
private:
virtual void Func(int x) = 0;
friend class Attorney;
public:
virtual ~Base() {}
};
class Derived : public Base {
private:
virtual void Func(int x) {
// This is called even though main is not a friend of Derived.
cout << "Derived::Func" << endl;
}
public:
~Derived() {}
};
class Attorney {
private:
static void callFunc(Base & b, int x) {
return b.Func(x);
}
friend int main();
};
int main() {
Derived d;
Attorney::callFunc(d, 10);
}
Boost.Iterators library
Boost.Serialization: class boost::serialization::access
없음
Bolton, Alan R. (01 January 2006). "Friendship and the Attorney-Client Idiom - Dr. Dobb's".
https://drdobbs.com/friendship-and-the-attorney-client-idiom/184402053
+글 내용 잘못된 거 있으면 제 변호사한테 연락주세요