2010-12-29 15 views
9
class B { 
virtual int foo(); 
}; 

class D : public B { 
virtual int foo() { cout<<"D\n"; } 
}; 

int B::foo() 
{ 
    /* how do i tell if this->foo() is overridden by a subclass, or if it will */ 
    /* simply recurse into B::foo()? */ 
    this->foo(); 
} 

main() 
{ 
D d; 
d.B::foo(); 
} 
+3

शायद कोई विश्वसनीय तरीका नहीं है। आपको क्यों चाहिए होगा? –

+0

मैं ओली से सहमत हूं- बस एक सामान्य व्यक्ति की तरह d.foo() को कॉल करें। – Puppy

+1

मैं विचारों के कुछ अतिरिक्त व्यक्तिगत बिंदुओं के साथ अपना उत्तर पूरक करना चाहता हूं। मैं कभी भी सवाल नहीं करता कि कोई ऐसा कुछ क्यों करना चाहता है। मैं संभवतः नहीं जानता कि वे कुछ क्यों करना चाहते हैं, मुझे पता है कि उन्होंने एक सवाल पूछा है।मुझे लगता है कि उनकी समस्या को हल करने और हल करने के लिए ठीक है और एक विकल्प प्रदान करें, जिनके बारे में सोचा नहीं जा सकता है, लेकिन "सामान्य व्यक्ति की तरह ऐसा करना" कथन रचनात्मक या सहायक नहीं हैं। –

उत्तर

8

उत्तर से कोई विधि ओवरराइड करता है उत्तर: आप नहीं कर सकते हैं।

यदि विस्तार करने के लिए कुछ भी था तो मैं विस्तार करूँगा।

+0

यही मैंने सोचा था। – deltamind106

0

सबसे सुरक्षित तरीका foo() को ओवरराइड नहीं कर रहा है, लेकिन बेसफैस से कॉल किए जाने वाले ऑनफू() फ़ंक्शन को ओवरराइड करने की अनुमति दें, यदि आप अपने प्रोग्रामर पर भरोसा नहीं कर सकते हैं। एमएफसी कुछ डिफ़ॉल्ट व्यवहार सुनिश्चित करने के लिए बहुत कुछ करता है (पुनरावृत्ति के खिलाफ सुरक्षा के बजाय)।

फिर, एक स्थिर स्तर पर, ऑनफू() को लागू करने वाली कुछ भी आसानी से 'फाइलों में खोजें' के साथ देखी जाती है।

उदा। ..

class B 
{ 
public: 
    B() 
    { 
     m_bInFoo=false; 
    } 

    int foo() 
    { 
     if(!m_bInFoo) 
     { 
      m_bInFoo=true; 

      int nRet = OnFoo(); 

      m_bInFoo=false; 

      return nRet; 
     } 

     return 0;// probably throw exception 
    } 

protected: 
    // inherited classes override OnFoo(), and never call OnFoo(); 
    virtual int OnFoo(){ return 0 }; 

private: 
    bool m_bInFoo; 
} 
1

मैं भी इस प्रदान करने से नफरत है (वाक्य रचना/संकलन और नहीं threadsafe के लिए परीक्षण नहीं) लेकिन यहाँ यह

int B::foo() 
{ 
std::cout << "B" << std::endl; 
if (typeid (*this) != typeid(B)) 
    this->foo(); 
return 0; 
} 

संपादित

है मैं साबित होता है कि यह काम करता है चाहता हूँ एमएसवीसी ++ 2010 में।

#include "stdafx.h" 
#include <iostream> 

class B { 
public: 
virtual int foo(); 
}; 

class D : public B { 
public: 
virtual int foo() { 
    std::cout<<"D\n"; return 0; 
} 
}; 

int B::foo() 
{ 
std::cout << "B" << std::endl; 

/* how do i tell if this->foo() is overridden by a subclass, or if it will */ 
/* simply recurse into B::foo()? */ 
if (typeid (*this) != typeid(B)) 
    this->foo(); 

return 0; 
} 


int main(int argc, _TCHAR* argv[]) 
{ 
D d; 
d.B::foo(); 

B b; 
b.foo(); 
return 0; 
} 

Ou tput

B 
D 
B 

सबूत यह हमेशा इस को

डी बदलें काम नहीं करेगा और यह काम नहीं करेगा अब

class D : public B { }; 
+0

यह काम नहीं करता है। यह नहीं बता रहा है कि foo() को ओवरराइड किया गया है, और वास्तव में यदि आपका कोड नहीं है तो किसी ऑब्जेक्ट पर foo() पर किसी भी कॉल पर असीमित रूप से रिकॉर्ड्स होगा; ठीक है ओपी क्या टालना चाहता है। यह वास्तव में इससे परे कुछ भी पता लगाने में आपकी सहायता नहीं करता है कि बी कि foo() को कॉल किया जा रहा है या नहीं, वास्तव में एक अधिक निर्दिष्ट संस्करण है या नहीं ... यह है। अगर जवाब उत्तर की वैधता की जांच करने से पहले लोगों ने उन्हें बाहर नहीं किया तो अंक अधिक अर्थपूर्ण होंगे। –

+0

@ नूह रॉबर्ट्स आप सही हैं, अगर डी बी :: foo ओवरराइड नहीं करता है तो यह रिकर्स होगा। इसे अवांछित ढेर का उपयोग करके भी हल किया जा सकता है। बी :: foo() में प्रवेश करने के बाद थ्रेड स्थानीय स्टोरेज में ध्वज सेट करने वाले स्टैक पर एक वैरिएबल सेट करें, यदि बी: foo() एक ही स्टैक के माध्यम से फिर से दर्ज किया गया है, और एक और चर बनाने की कोशिश करता है, तो यह देखने के लिए जांच सकता है कि क्या ध्वज सेट किया गया है और फिर बाहर निकलें। एक बार जब ढेर चर के विनाश को खोलता है तो ध्वज को अनसेट कर सकता है। मेरा समाधान उसने जो सही समस्या दी है, वह हल करती है, जो मेरी गलती है क्योंकि मैंने अन्य परिदृश्यों में पढ़ा नहीं था जो हो सकता था। –

2

एक दृष्टिकोण foo()शुद्ध आभासी समारोह बनाने के लिए हैB, और भी इसे परिभाषित करता है। इस तरह आप सुनिश्चित करते हैं कि Bके व्युत्पन्न वर्गfoo() को परिभाषित करना चाहिए। यहाँ बी,

class B 
{ 
public: 
     virtual int foo() = 0; //pure virtual function 
}; 

//pure virtual function also has a default implementation! 
int B::foo() 
{ 
     std::cout << "B" << std::endl; 
     this->foo(); //this will call the overridden foo() in the derived class! 
     return 0; 
} 

बी के एक व्युत्पन्न वर्ग foo() को लागू नहीं करता है, तो आप भी इस तरह के व्युत्पन्न वर्ग का उदाहरण नहीं बना पा रहा है!

ideone पर पूरा काम कर कोड देखें: http://www.ideone.com/m8O2s

वैसे, मेरी निजी राय हो सकता है, वर्गों में से इस तरह के डिजाइन के साथ शुरू करने के लिए बुरा है। क्या होगा यदि आप derive class foo() से B::foo() पर कॉल करते हैं? पुनरावर्ती?

+0

यह ऐसा करता है ताकि वह बी के उदाहरण को तुरंत चालू नहीं कर सके। हम नहीं जानते कि वह अभी भी बी –

+0

की वस्तुएं बनाना चाहता है, हां, मुझे पता है कि इसके चारों ओर इंजीनियर करने के तरीकों का एक समूह है, लेकिन मेरा प्रश्न यह है कि यदि मैं चाहता हूं तो सी ++ आरटीआई में एक रास्ता बनाया गया है। – deltamind106

0

जैसा कि अन्य ने बताया है, ऐसा करने का कोई विश्वसनीय तरीका नहीं है। मैं आपको अपने डिजाइन पर पुनर्विचार करने का आग्रह करता हूं ...

+0

अच्छी तरह से, हाँ, यह अच्छा होगा अगर मैं पिछले डेवलपर के अजीब कोड को फिर से डिजाइन कर सकता हूं, लेकिन हां, जो अभी कार्ड में नहीं है। – deltamind106

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