2016-07-21 7 views
7

मैं std::bind का उपयोग करें और आधार वर्ग समारोह जैसे गैर आभासी कॉल करना चाहते हैं: derived_obj.BaseClass::foo()std :: बाँध और गैर आभासी आधार वर्ग विधि करने के लिए कॉल


उदाहरण:

मान लीजिए कि मैं करते हैं बेस क्लास और व्युत्पन्न कक्षा बी में वर्चुअल फ़ंक्शन foo() है जो बी द्वारा ओवरराइड किया गया है।

class A 
{ 
    public: 
    virtual void foo() { std::cout << "Hello from A::foo()!";} 
} 

class B : public A 
{ 
    public: 
    void foo() overide { std::cout << "Hello from B::foo()!";} 
} 

मैं कक्षा बी की वस्तु से A::foo() कॉल करने के लिए चाहते हैं मुझे क्या करना गैर आभासी कॉल:

B b_obj; 
b_obj.A::foo(); // prints "Hello from A::foo()!" 


अब मैं std::bind का उपयोग और गैर आभासी क्या करना चाहते हैं b_obj से A::foo() पर कॉल करें, मैं यह कैसे कर सकता हूं?

मैं पहले से ही को b_obj कास्टिंग &A::foo() का एक और उपयोग पता द्वारा की कोशिश की है, लेकिन कोई किस्मत थी।

auto f = std::bind(&A::foo, static_cast<A*>(&b_obj)); 
f(); // prints "Hello from B::foo()!" but it should print "Hello from A::foo()!" 
+1

आप लैम्बडा को कॉल लपेट सकते हैं। यह देखते हुए कि बाइंड के साथ इसे कैसे करना है। – Zereges

उत्तर

2

आपके यहां दो विकल्प हैं। आपको लैम्ब्डा में गैर-वर्चुअल कॉल करना चाहिए या आप का भरोसेमंद पुराना तरीका ऑब्जेक्ट (जो एक प्रति है) को स्लाइस करना चाहते हैं, जिसे आप std::bind पर पास करना चाहते हैं।

// Base method 
B b_obj; b_obj.A::foo(); // prints "Hello from A::foo()!" 

// First method 
auto k = [](auto b){ b.A::foo(); }; 
k(b_obj); 

// Second method 
auto f = std::bind(&A::foo, *static_cast<A*>(&b_obj)); 
f(); 

यह सब प्रिंट:

Hello from A::foo()! 
Hello from A::foo()! 
Hello from A::foo()! 

दूसरी विधि (स्लाइस) काम करता है std::bind प्रतियां अपने तर्कों के बाद से। आपको वास्तव में एक लैम्ब्डा पसंद करना चाहिए।

+1

आप यहां एक अलग ऑब्जेक्ट के साथ बाध्य कहते हैं - आपने b_obj के आधार पर टाइप ए की एक नई प्रति बनाई है। – Dutow

+0

@Dutow, स्लाइस करने का कोई बेहतर तरीका है? – WhiZTiM

+0

@Dutow इसे इंगित करने के लिए धन्यवाद। मैंने इसे लैम्ब्डा और 'std :: bind' के संयोजन से हल कर लिया है जैसे कि 'std :: bind ([] (auto * b) {b-> ए :: foo();}, और b_obj);' – Allin

1

आप एक लैम्ब्डा के अंदर कॉल लपेट सकता है:

B b_obj; 
auto f = std::bind([&b_obj]() { b_obj.A::foo(); }); 

लेकिन इस छोटी सी भावना जब तक आप केवल (std::is_bind_expression की वजह से उदाहरण के लिए) कहीं std::bind उपयोग कर सकते हैं बनाता है, जैसा कि आप लैम्ब्डा के कब्जा करने के लिए वस्तु पैरामीटर पारित बांधने के लिए नहीं।

अन्यथा केवल bind के बिना लैम्ब्डा या std::function का उपयोग क्लीनर होना चाहिए।

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