2016-06-08 10 views
5

मैं सूचक-टू-कार्यान्वयन मुहावरे के साथ अपरिवर्तनीय वस्तुओं पर एक सजावटी पैटर्न लागू कर रहा हूं। मूल रूप से मेरी सेटअप इसक्या यह पता लगाना संभव है कि ऑब्जेक्ट सदस्य फ़ंक्शन के भीतर से अस्थायी है या नहीं?

struct Object : ObjectBase { 
    void doSmth() override { 
     impl->doSmth(); 
    } 
    // this is the function I'd like to implement 
    Object decorateWith(std::unique_ptr<ObjectDecorator>&&); 
private: 
    std::unique_ptr<ObjectBase> impl; 
}; 

struct ObjectDecorator : ObjectBase { 
    void doSmth() override { 
     // do some stuff 
     impl->doSmth(); 
     // do some more stuff 
    } 
private: 
    std::unique_ptr<ObjectBase> impl; 
}; 

यहाँ की तरह दिखता है, decorateWith समारोह पर कि क्या वस्तु उस पर Callen है एक अस्थायी या नहीं है निर्भर करता है अलग व्यवहार कर माना जाता है। यदि इसे एक गैर-अस्थायी वस्तु पर बुलाया जाता है, तो इसे एक नया ऑब्जेक्ट उदाहरण वापस करना होता है जहां मुझे वर्तमान ऑब्जेक्ट की गहरी प्रतिलिपि बनाना होता है और इसे सजावट के अद्वितीय_ptr में संग्रहीत करना होता है जबकि नए ऑब्जेक्ट के इन्स पॉइंटर सजावटी को इंगित कर रहा है। यदि, हालांकि, सजाने के साथ एक अस्थायी पर बुलाया जाता है, तो ऑब्जेक्टडिक्टर को बनाने के लिए पर्याप्त होता है और केवल वर्तमान ऑब्जेक्ट के इंप-पॉइंटर को सजावटी के इंप पॉइंटर में ले जाता है और ऑब्जेक्ट को नए सजावट को इंगित करने देता है।

छेड़छाड़ करने के लिए मुझे कॉल करने के लिए कॉल के भीतर से निर्धारित करने का एक तरीका चाहिए कि क्या वस्तु अस्थायी है या नहीं और फिर उस चेक के परिणामस्वरूप टैग-प्रेषण का उपयोग करें। क्या यह संभव है?

बेस्ट Xodion

संपादित करें: नमूना फोन करने वाले कोड ऐसा दिखाई दे सकता:

  • decorateWith पर एक गैर अस्थायी

    int main() { 
        Object x{}; 
    
        // this call does not modify x so it can be reused later 
        Object y = x.decorateWith{std::make_unique<ObjectDecorator>()}; 
        y.doSmth(); 
    
        // do some other stuff here 
    
        // here, if I had moved the impl-unique_ptr in the decorateWith 
        // call this would now segfault since I'd call nullptr->doSmth(); 
        x.doSmth(); 
    
    } 
    
  • decorateWith कहा जाता है एक अस्थायी पर कहा जाता है

    int main() { 
        Object x = Object{}.decorateWith(std::make_unique<ObjectDecorator>()) 
             .decorateWith(std::make_unique<ObjectDecorator>()) 
             .decorateWith(std::make_unique<ObjectDecorator>()); 
        // in this case it would be unneccessary to make a deep copy of all 
        // previous instances so I'd like to only move the impl poiner every time 
        x.doSmth() 
    } 
    
+1

आपकी स्पष्टीकरण नमूना कॉलिंग कोड के साथ बेहतर तरीके से समर्थित हो सकती है। – kfsone

+2

क्या आप यह निर्धारित करने के लिए कह रहे हैं कि 'ऑब्जेक्ट' 'सजाने के साथ 'कहा जाता है अस्थायी है, या यदि' सजाने के लिए तर्क 'अस्थायी है या नहीं? – md5i

+0

मैं सशर्त रूप से केवल तभी स्थानांतरित करना चाहता हूं जब जिस वस्तु को सजाने के साथ बुलाया जाता है वह अस्थायी होता है और अन्यथा गहरी प्रतिलिपि बनाता है, इसलिए यह जांचना है कि कोई ऑब्जेक्ट अस्थायी है या नहीं। जैसा कि नीचे दिए गए उत्तरों से पता चलता है कि किसी प्रकार की प्रकार की विशेषता की आवश्यकता नहीं है क्योंकि कोई रेफ-क्वालीफायर का उपयोग करके अधिभारित कर सकता है। – Corristo

उत्तर

12

आप सदस्य कार्यों पर ref-qualifiers प्राप्त कर सकते हैं। से en.cppreference.com

#include <iostream> 
struct S { 
    void f() & { std::cout << "lvalue\n"; } 
    void f() &&{ std::cout << "rvalue\n"; } 
}; 

int main(){ 
    S s; 
    s.f();   // prints "lvalue" 
    std::move(s).f(); // prints "rvalue" 
    S().f();   // prints "rvalue" 
} 
अपनी स्थिति में

तो कॉपी किए गए उदाहरण, तो आप इस

Object decorateWith(std::unique_ptr<ObjectDecorator>&&) &; 
Object decorateWith(std::unique_ptr<ObjectDecorator>&&) &&; 
+0

हां, वास्तव में, लेकिन फिर भी रेफ-क्वालीफायर मुझे चाहिए। – Corristo

4

आप संदर्भ क्वालिफायर का उपयोग कर सकते जिस तरह से आप const का उपयोग करेंगे के समान सदस्य समारोह ओवरलोड की तरह कुछ करना चाहते हैं const और गैर const वस्तुओं के लिए ओवरलोड:

Object decorateWith(std::unique_ptr<ObjectDecorator>&&) const& 
{ 
    // implementation if this is not a temporary 
} 

Object decorateWith(std::unique_ptr<ObjectDecorator>&&) && 
{ 
    // implementation if this IS a temporary 
} 
2

हां। आप निम्न दो विधियों लागू करते हैं तो:

Object decorateWith(std::unique_ptr<ObjectDecorator>&&) &; 
Object decorateWith(std::unique_ptr<ObjectDecorator>&&) &&; 

अगर *this एक rvalue है दूसरा बुलाया जाएगा।

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