2014-07-26 5 views
5

मेरे पास एक संदेश प्रणाली है जहां मैं विभिन्न कार्यों के लिए एक संरचना पास करता हूं। एक संक्षिप्त उदाहरण में, संदेश इस तरह वर्णित है:एक कॉन्स्ट घोषित ऑब्जेक्ट अपरिभाषित व्यवहार पर एक म्यूटेबल को संशोधित कर रहा है?

struct Message { 
    bool wasHandled; 

    Message() { 
     wasHandled = false; 
    } 
}; 

और संदेश हैंडलर इस तरह शुरू हो जाती है:

handleMessage(Message()); 

संदेश स्थिरांक संदर्भ के रूप में पारित कर रहे हैं। इसके लिए मेरा मुख्य प्रेरणा है इसलिए मैं उपरोक्त एक-लाइनर लिख सकता हूं। गैर स्थिरांक संदर्भ द्वारा पारित अगर मैं लिखने के लिए होगा:

Message message; 
handleMessage(message); 

संभाल ध्वज इंगित करता है संदेश समारोह ने संभाला। फ़ंक्शन handleMessage इस प्रकार wasHandled ध्वज को संशोधित करने की आवश्यकता है। एक संभावित क्रियान्वयन होगा:

void handleMessage(const Message& message) { 
    const_cast<bool&>(message.wasHandled) = true; 
    // Do stuff here. 
} 

हालांकि, मेरी समझ के अनुसार,

handleMessage(Message()); 

बराबर है करने के लिए:

const Message message; 
handleMessage(message); 
: ( नोट यह गलत है, स्वीकार किए जाते हैं जवाब देखें)

इसलिए मैं एक कॉन्स ऑब्जेक्ट का मान बदल रहा हूं। वह अपरिभाषित व्यवहार है।

struct Message { 
    mutable bool wasHandled; 

    Message() { 
     wasHandled = false; 
    } 
}; 

यह व्यवहार के रूप में परिभाषित संदेश की घोषणा करेंगे? यह निश्चित रूप से कॉन्स कास्ट भी हटा देगा।

ध्यान दें कि इस विशेष उदाहरण में wasHandle ध्वज वास्तव में कभी नहीं पढ़ा जाता है, और यदि कॉलर इसके बारे में जानना चाहता है तो एक-लाइनर का उपयोग नहीं किया जा सकता है। हालांकि, हकीकत में सभी कॉलर्स ध्वज में रुचि नहीं रखते हैं। यह संदेश handleMessage के अंदर अन्य कार्यों में भी भेजा जा सकता है जो ध्वज का उपयोग करता है।

+0

@juanchopanza:

तुम सच में एक जैसे परिवर्तनशील lvalues ​​और rvalues ​​को संभालने के लिए (और यह बहस का मुद्दा है कि क्या है कि कुछ अन्य डिजाइन समस्याओं का एक लक्षण नहीं है) चाहते हैं, तो आप बस दो समारोह भार के होना चाहिए यह समस्या को कैसे दूर करेगा? फ़ंक्शन हैंडल मैसेज को अभी भी ध्वज को संशोधित करने की आवश्यकता है। और AFAIK रचनाकारों को कॉन्स्ट-घोषित वस्तुओं पर भी सदस्यों को संशोधित करने की अनुमति है। – rasmus

+4

आप mutable के साथ क्या कर रहे हैं अपरिभाषित व्यवहार नहीं है। यह mutable का पूरा बिंदु है। –

+0

क्षमा करें, मैं आधा सो रहा हूँ। हां यह ठीक है। यही है कि 'mutable' के लिए है। – juanchopanza

उत्तर

4

आपके पास जो जटिल है वह अत्यधिक जटिल है। सबसे पहले, अस्थायी वस्तुओं की आपकी समझ गलत है। Message() एक पूरी तरह से परिवर्तनीय मूल्य है। यह सिर्फ इतना है कि यह एक रावल्यू होने के कारण, lvalue संदर्भ से बंधे नहीं जा सकता है।

void handleMessage(Message & m) { handleImpl(m); } 
void handleMessage(Message && m) { handleMessage(m); } 
+0

आपको हैंडल की आवश्यकता नहीं है Ipl, rvalue ref overload lvalue ref one में स्वतंत्र रूप से प्रतिनिधि हो सकता है। – Puppy

+0

@Puppy: दरअसल, अच्छा बिंदु। –

+0

धन्यवाद। मैं इस संदर्भ में रावल संदर्भों के बारे में भूल गया। मैं curios हूँ: पूर्व सी ++ 11 के बारे में क्या? चूंकि रैल्यू संदर्भ मौजूद नहीं हैं, फिर भी अस्थायी अभी भी परिवर्तनीय हैं? – rasmus

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

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