2010-03-31 6 views
7

검사 할 C++ 클래스가 있습니다. 그래서, 나는 나가기 전에 매개 변수와 반환 값을 모든 메서드에서 출력하고 싶습니다.C++에서 모든 메서드 호출에 대해 특정 코드 실행

후자는 다소 쉽습니다. 나는 모든 것을()를 호출 할 경우 매크로

#define return(a) cout << (a) << endl; return (a) 

내가 모든 수익을 padronize 경우 괄호에 (잘못 될 수도 있습니다) 그것을 할 것 (또는 무엇이든이 호출 할 수 있습니다). 이 문제를 해결하려면 정의를 주석으로 처리하십시오.

그러나 입력을 인쇄하는 것이 더 어려워 보입니다. C++ 구조를 사용하거나 workaroud 해킹을 사용하여 내가 할 수있는 방법이 있습니까?

+4

디버거를 사용할 수없는 이유가 있습니까? – tloach

+0

예, 데이터를 처리하기 위해 입력 및 출력을 파일로 보내려고합니다. 메소드를 디버그하고 싶지는 않습니다. 분명히 정확하고 잘 테스트되었습니다. –

답변

4

그러나 인쇄 입력이 더 많은 것 같습니다 . 내가 할 수있는 방법이 있습니까? C++ 구조체를 사용하거나 workaroud 해킹을 사용합니까?

번호


업데이트 : 당신은 아마 당신이 Design by Contract을 적용하여 필요한 달성 할 수 있음을 제안하여 내 대답에 약간의 간결성을 잃을거야.

+2

짧고, 달콤한, 요점은 정확합니다. +1. –

2

저에게 디버깅 유틸리티를 사용하려는 것 같습니다. 그러면 원하는 모든 매개 변수를 볼 수 있습니다.

+0

매개 변수를보고 싶지 않습니다. 나는 유틸리티의 일부가 아닌 통계 연구와 같은 다른 것을하기 위해 그것들 모두를 출력하고 싶다. –

1

방법이 모두 virtual 인 경우 decorator-pattern을 사용하면 아주 세련된 방식으로이를 구현할 수 있습니다.

편집 : 위의 의견 (통계 결과를 원합니다)에서 나는 decorator-pattern을 사용해야한다고 결론을 내 렸습니다. 그것은 이런 종류의 물건을위한 것입니다.

+0

서브 클래 싱은 이와 같은 상황에서 동일한 결과를 얻을 수 있습니다. 그렇습니까? 그러나 그것은 내가 찾고있는 것이 아닙니다! 데코 레이팅과 하위 클래스 화 모두 더티 트릭 (모든 곳에서 인화)보다 동일한 양의 코드를 작성해야합니다. 그러나 발신자 코드도 변경해야합니다. –

+0

글쎄, 당신의 프로필에서 당신은 좋은 디자인을 좋아한다고 말합니다. 슬프게도, C++의 디자인 패턴을 구현하는 데 항상 보일러 플레이트가 많이 있지만, 여전히 높은 유연성을 얻습니다. –

+0

예, 디자인 패턴이 정말 좋기 때문에 GoF가 매번 내 테이블에 앉을 수있는 유일한 책입니다. 하지만 나는이 사건이 과잉이라고 생각한다. 나는 개발자를 위해 일시적으로 "켜기"/ "끄기"기능을 원합니다. –

8

몇 가지 옵션이 마음에 와서 :

  • 디버거를 사용합니다.
  • Space_C0wb0y 제안대로 decorator pattern을 사용하십시오. 그러나 데코 레이팅 된 클래스의 모든 메서드를 복제하고 직접 로깅을 추가해야하므로 수동 타이핑이 많이 필요할 수 있습니다. 어쩌면 당신은 클래스에 Doxygen을 실행 한 다음 출력을 파싱하여 데코레이터 객체를 자동화 할 수 있습니다.
  • aspect-oriented programming을 사용하십시오. (당신이하고 싶은 로깅은 AOP의 일반적인 응용 프로그램입니다.) Wikipedia lists C++에 대한 몇 가지 AOP 구현 : AspectC++, XWeaverFeatureC++.
+0

+1 AOP 팁! 그러나 디버거를 사용하여 나에게 제안한 사람에게 한 염려를 읽고 Space_C0wb0y –

+0

데코 레이팅 또는 서브 클래 싱을하면 호출자 코드를 변경할 수 있습니다. 할 수있을지라도 나는 싫어합니다. 생성 된이 클래스의 모든 객체에 데코 레이팅 호출을 두지 않고 정의 (#ifdef STATS ... #endif)를 사용하여 변경을 수행하는 것이 좋습니다. –

2

당신이 손으로 몇 가지 코드를 삽입 괜찮다면, 당신은 클래스를 만들 수 있습니다 생성자

  • 의 방법

    1. 로그 항목이 임의의 매개 변수
    2. 를 덤프하는 방법을 제공합니다
    3. 는 소멸자에 상태를 기록한 상태
    4. 로그 출구를 기록하는 방법을 제공한다

    사용법 같은 것을 보일 것이다 : 물론

    unsigned long long 
    factorial(unsigned long long n) { 
        Inspector inspect("factorial", __FILE__, __LINE__); 
        inspect.parameter("n", n); 
        if (n < 2) { 
         return inspect.result(1); 
        } 
        return inspect.result(n * fact(n-1)); 
    } 
    

    을, 당신은 관리자를 선언하고 매개 변수를 검사하는 매크로를 기록 할 수 있습니다. 당신이 AOP처럼 뭔가에 가지 않고 깔끔한 솔루션을 얻을 수 있는지 확실하지 않습니다

    unsigned long long 
    factorial(unsigned long long n) { 
        INJECT_INSPECTOR(n); 
        if (n < 2) { 
         return INSPECT_RETURN(1); 
        } 
        return INSPECT_RETURN(n * fact(n-1)); 
    } 
    

    : 당신이 변수 인수 목록 매크로를 지원하는 컴파일러로 작업하는 경우에, 당신은 같이하는 결과를 얻을 수 있습니다 환경 또는 일부 사용자 정의 코드 생성 도구.

  • +0

    좋은데 varargs에는 문제가있을 수 있습니다. C++은 varargs 함수와 잘 작동하지 않으며, 결국은 사용할 필요가 있습니다. 지원되지만 사실 C 값만 지원됩니다. –

    +0

    나는 공식적으로 C++로 몰래 빠져 나가지는 않았지만,'INJECT_INSPECTOR'에 대한 가변 인자 목록 _macros_을 생각하고있었습니다. C++의 Varargs 함수는 실제로 어떤 방식 으로든 사용하기 위해 손상되었습니다. 나는 각 매개 변수에 대해 별도의'매개 변수 (이름, 값)'호출을 사용하고, 호출을 템플릿으로 만들고, 형식화를 위해 iostream을 활용할 것이다.나는 실제와 비슷한 것을 사용하고있다;) –

    0

    로깅 라이브러리 (또는 일부 매크로)를 사용하고 수동 로깅 호출을 삽입하기 만하면됩니다. 클래스에 지나치게 많은 메소드가 없으면보다 정교한 솔루션을 개발하고 디버깅하는 것보다 빠르다는 것이 더 빠를 것입니다.

    +0

    로깅은 그가 찾고있는 것을 잘 할 수 있으며, 각 줄을 인쇄하는 것보다 약간 깔끔할 것이다. 그러나 그가 이미 가지고 있지 않다면 추가 라이브러리가있을 것이다. –

    관련 문제