S T U D Y/C++

오늘 스터디하면서 아리달쏭했던거

알 수 없는 사용자 2008. 7. 16. 00:13
Effective C++ 263page에 나오는 내용



* review

우선 NVI 를 통해 템플릿메소드패턴을 구현하는 방법에 대해 알아보았어요!


  214 class 부모

  215 {

  216 private:

  217     virtual Dofunction()

  218     {

  219     // 자식이 상속받아서 재정의할수있음

  220     // private에 있으므로 절대 호출은할수없지만 재정의!만 가능

  221     }

  222 public:

  223     func()

  224     {

  225         // 사전작업. 공통된 루틴

  226         Dofunction();

  227         // 사후작업. 공통된 루틴

  228     }

  229 };

  230 

  231 class 자식 : class 부모

  232 {

  233     virtual Dofunction()

  234     {

  235         //자식마다 그때그때 다른루틴을 이곳에

  236     }

  237 };





이걸 응용해서
함수포인터로 구현한 전략패턴

  239 typedef int (*FuncPointer)(double);

  240 //double을 매개변수로 가지며

  241 //int를 리턴하는 함수를 위한 포인터를

  242 //Func라고 정의해주는 define문

  243 

  244 Function( FuncPointer fp )

  245 {

  246     // 사전작업

  247     fp();

  248     // 사후작업

  249 }



이렇게 해줬을때의 문제점?

-> 저 펑션은 지금 전역함수가아닌가?
그렇다면 클래스 내부의 private에 감춰진 멤버변수들에 접근이 불가능해지므로
몹시 불편해진다.

고로 우리가 찾은 해결책.

std::tr1::function<int (double)> FuncPointer;

저 위에 펑션포인터보다 훨씬 더 똑똑하다.
tr1의 function계열의 객체는 전역함수포인터, 멤버함수포인터, 함수객체까지 담을수 있어요!

그러나 이렇게했을때의 문제점은?

-> 우리가 만약 멤버함수포인터를 넘긴다면
멤버함수 포인터는 저 위에  써준 함수의 시그너쳐에 맞게

더블타입만을 매개변수로 가질것같은 느낌이들지만
사실은 그렇지않죠.

클래스의 멤버변수이기때문에 기본적으로 멤버함수에는
우리눈에 보이지않는 인자가 숨어있어요
자기가 어떤 객체에서 호출될 함수인지 알아야하기때문에
객체이름이 숨어있다고 볼수있죠

그래서 사실상
int를 리턴하며 void를 받아오는 함수가 아니라서
FuncPointer로는 취급할수 없어져버린다는 결론

고로 여기서 또다른 솔루션

  244 Function( FuncPointer fp )

  245 {

  246     // 사전작업

  247     fp();

  248     // 사후작업

  249 }

이 함수를 호출할때

Function(  std::tr1::bind(클래스이름::멤버함수이름, 객체이름)  );

이렇게 써주시면 되어요
여기서 bind의 역할은

위에 노란형광펜 부분에 있는 '객체이름'에 쓰여진
이름의 객체가 인자로 넘어가는거죠!

Function의 매개변수로 넘어가야 할 값은
보통의 경우

Function(a); // double을 매개변수로 가지고 int를 리턴하는 함수포인터 a를 인자로 넘길께.

그렇지만

Function(  std::tr1::bind(AAA::func, Name)  );

이 경우엔?
AAA클래스에서 double을 매개변수로 가지고 int를 리턴하는데
Name객체에서 실행되는 함수포인터를 인자로 넘길께!!!!!!!!!!!!!!!!!!!!!!

ㅇㅋㅇㅋ?

우리가 아리달쏭했던 부분은 단지
바인드가 뭐하는앤가? 였는데 너무 장황하게 설명한건
그냥 복습차 ㅋㅋ

그럼 안녕히들주무세여-