2013-07-25 172 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'的函數應該是class,因此'blah'應該是private的。你不能將'foo'的代碼移動到'MyClass'的構造函數中嗎? – stefan

回答

5

不,這是不可能的,沒有其他變量告訴你。你可以做的最好的事情就是製作方法private,這樣只有你的班級可以調用它。然後確保只有構造函數調用它。除此之外,它只需要構造函數調用它,你試過不使用函數,只是把代碼放在那裏

+0

在實踐中,函數被多次調用不同的參數。但是,您的斜體評論確實讓我覺得我們可以用'#define' /'#undef'將它帶入/超出範圍。 –

相關問題