2012-01-27 23 views
7

से संरक्षित सदस्यों तक पहुंचें ठीक है, इसलिए वर्चुअल फ़ंक्शन लुक-अप से बचने के लिए मैं यहां संशोधित CRTP रूट का एक प्रकार ले रहा हूं।टेम्पलेटेड (स्थिर) सदस्य फ़ंक्शन

class A 
{ 
public: 
    static void foo(A *pA) 
    { 
     pA->bar(); 
    } 

protected: 
    virtual void bar() 
    { 
     TRACE0(_T("A::bar\n")); 
    } 
}; 

class B : public A 
{ 
protected: 
    virtual void bar() 
    { 
     TRACE0(_T("B::bar\n")); 
    } 
}; 

जो करने की उम्मीद के रूप में काम करता है::

class A 
{ 
public: 
    template <class T> 
    static void foo(T *pT) 
    { 
     pT->bar(); 
    } 

protected: 
    void bar() 
    { 
     TRACE0(_T("A::bar\n")); 
    } 
}; 

class B : public A 
{ 
protected: 
    void bar() 
    { 
     TRACE0(_T("B::bar\n")); 
    } 
}; 

जो देता है लेकिन मैं सिर्फ एक त्रुटि यह मुझे देता है ...

तो मैं अनुवाद करने के लिए कोशिश कर रहा हूँ नहीं समझ सकता त्रुटि:

error C2248: 'B::bar' : cannot access protected member declared in class 'B' 
see declaration of 'B::bar' 
see declaration of 'B' 
see reference to function template instantiation 'void A::foo<B>(T *)' 
being compiled with 
[ 
    T=B 
] 

अब मुझे पता है, यह आसानी से वर्ग बी के friend class A; जोड़कर तय हो गई है, लेकिन यह नहीं है बहुत साफ़। क्या कोई दूसरा रास्ता नहीं है?

संपादित करें: उदाहरण उपयोग:

B b; 
b.foo<B>(&b); 

संपादित करें # 2: सदस्य समारोह foo स्थिर कोई फर्क नहीं पड़ता मैंने देखा जा रहा है।

+0

मुझे लगता है कि ऐसा होता है क्योंकि माता-पिता वर्गों में बच्चे के संरक्षित सदस्यों तक विशेष पहुंच नहीं है (क्या वे?)। यह केवल बच्चों के माता-पिता तक पहुंचने के लिए काम करता है। –

+1

जैसा कि ज़ैन ने कहा था, एक अभिभावक वर्ग व्युत्पन्न वर्ग के संरक्षित सदस्यों तक नहीं पहुंच सकता है (जब तक कि यह निश्चित रूप से मित्र न हो) –

+0

सही के बारे में लगता है ... 'A :: foo'' B :: bar' को कॉल करने का प्रयास कर रहा है और असफल रहा क्योंकि इसकी रक्षा हुई। 'मित्र वर्ग ए' उचित समाधान की तरह लगता है। –

उत्तर

2

पहला मामला bar में आभासी समारोह है और fooA के सूचक के माध्यम से उसके द्वारा पहुंच इस प्रकार समारोह सूचक और vtable की निर्दिष्ट सूचकांक लागू के रूप में वर्ग A द्वारा layout'ed। इस प्रकार यह काम करता है।

हालांकि, दूसरे मामले में, A::foo स्पष्ट रूप से अलग-अलग वर्ग से गैर-वर्चुअल फ़ंक्शन को कॉल करता है, इसकी कोई पहुंच नहीं है। B::barA::bar का आभासी अधिभार नहीं है - यह पूरी तरह से असंबंधित कार्य है।

इसलिए, friend class A; बनाना सबसे अच्छा है जो आप प्राप्त कर सकते हैं, मुझे डर है।

संबंधित मुद्दे