2013-07-25 2 views
4

클래스의 동일한 인스턴스 (또는 해당 하위 클래스 중 하나)의 생성자 만 호출 할 수있는 비 정적 메서드를 만들고 싶습니다. 키 기반 액세스 보호 패턴에 미치지 못하는 우아한 방법이 있습니까?우리가 생성자 내부에서 호출되는지 여부를 알 수있는 방법이 있습니까?

class MyClass 
{ 
    public: 
    void foo() 
    { 
     assert(foo was called from the constructor); //how?! 
     if (some condition or other) 
      throw ExceptionThatOnlyClientsThatConstructTheObjectCanHandle(); //hence my requirement 
    } 
}; 

class MySubClass : public MyClass 
{ 
    public: 
    MySubClass() 
    { 
     blah(); //correct use of foo() through blah() 
     foo(); //correct use of foo() directly 
    } 
    void blah() { foo(); } //correctness depends on who called blah() 
}; 

int main() 
{ 
    MySubClass m; 
    m.foo(); // incorrect use of foo() 
    m.blah(); // incorrect use of foo() through blah() 
    return 0; 
} 

편집 : 아래에있는 내 의견을 볼 수 있지만, 나는이 (1) 전이 키 중심의 액세스 제어 또는 (2) 확인 예외를 처리하는 만드는 특별한 경우 중 하나라고 생각합니다. 그런 것을 보았을 때 생성자는 빨간 청어입니다.

+1

먼저 공개되지 않도록 설정하십시오. 이것은 생성자가 호출했는지 판단하는 데는 도움이되지 않지만 최소한 클래스의 사용자는 액세스 할 수 없습니다. 귀하의 질문의 핵심에 관해서는, 나는 프로그래머의 선의에 의존하는 것이 최선이라고 믿습니다. – syam

+0

기본 클래스 초기화 프로그램과 생성자 위임을 알고 있습니까? 그들은 당신이하려고하는 것이 무엇이든간에 봉사 할 수 있습니다. – Sneftel

+0

'blah'는'foo'를 호출하기 때문에'blah' 함수를 볼 수있는 유일한 클래스가 클래스 여야합니다. 따라서 'blah'는 private이어야합니다. 'foo'의 코드를'MyClass'의 생성자로 옮길 수 없습니까? – stefan

답변

5

아니요. 다른 변수가 없다면 불가능합니다. 당신이 할 수있는 가장 좋은 방법은 당신의 클래스가 그것을 호출 할 수 있도록 private 메소드를 만드는 것입니다. 그런 다음 생성자 만 호출해야합니다. 그 외에는 생성자가 호출하기를 원한다면, 함수를 사용하지 않고 을 시도해보고 거기에 코드를 넣으십시오.?

+0

실제로이 함수는 다른 인수로 여러 번 호출됩니다. 당신의 이탤릭체로 된 주석은'#define' /'# undef'을 사용하여 범위를 가져올 수 있다고 생각하게 만듭니다. –

관련 문제