2009-08-17 22 views
5

के सदस्य फ़ंक्शन तक पहुंचने के लिए मेरे पास कोड का यह स्निपेट है। इरादा प्रारंभिक डेटा की एक प्रति बनाना है। चूंकि मैं किसी भी तरह से प्रारंभिक डेटा को संशोधित नहीं कर रहा हूं, मुझे लगता है कि मुझे इसे एक कॉन्स्ट संदर्भ के रूप में पास करना चाहिए। हालांकि, संकलन करते समय मैं यह संदेश प्राप्त करता रहता हूं।सी ++ और कॉन्स - एक कॉन्स संदर्भ

\ src \ दृश्य \ SceneAnimationData.cpp (23) :। त्रुटि C2662: 'SceneTrackerData :: getRect': नहीं कर सकते परिवर्तित 'इस' से 'स्थिरांक SceneTrackerData' के लिए सूचक 'SceneTrackerData &'

#include "SceneTrackerData.h" 

void SceneAnimationData::SetupData(const SceneTrackerData &initialData) 
{ 
    // getRect(), points() and links() all return const pointers 
    CloneRect(initialData.getRect()); 
    ClonePoints(initialData.points()->values()); 
    CloneLinks(initialData.links()->values()); 
} 

void SceneAnimationData::CloneRect(const QGraphicsRectItem * initialRect) 
{ 
    if (initialRect != NULL) 
    { 
     QPointF position = initialRect->scenePos(); 
     QRectF rect = initialRect->rect(); 

     initialRect = new QGraphicsRectItem(rect); 
     initialRect->setPos(position); 
    } 
} 

void SceneAnimationData::CloneLinks(const QList<QGraphicsLineItem*> links) 
{ 
    links_ = new QList<QGraphicsLineItem*>(*links); 
} 

void SceneAnimationData::ClonePoints(const QList<QGraphicsEllipseItem*> points) 
{ 
    points_ = new QList<QGraphicsEllipseItem*>(*points); 
} 

उत्तर

13

SceneTrackerData की परिभाषा के बिना, यह कहना मुश्किल है, लेकिन संभावना है कि समारोह (SceneTrackerData::getRect) स्थिरांक के रूप में चिह्नित नहीं है।

है वह यह है कि क्या (अनुमान लगा):

const Rect& SceneTrackerData::getRect(void) 

होना चाहिए:

const Rect& SceneTrackerData::getRect(void) const 
         //     ^
         //      | 
         // does not logically modify the object 
+0

एक प्रश्न - getRect (शून्य) के लिए कोई आधार नहीं है कि मैं Rect को बदल नहीं सकता? मुझे पता है कि कंपाइलर इसे "देख" नहीं सकता है - लेकिन मेरा अनुमान है कि Rect के सभी तरीकों का आधार नहीं है। उनमें से सभी के बिना, आप Rect को बदलने में getRect पर भरोसा नहीं कर सकते हैं। क्या यह स्पष्ट होगा (इस मामले में) इसे जोड़ने के बजाए अन्य फ़ंक्शन में स्थिरता को दूर करने के लिए? –

+1

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

1

यह जो लाइन 23 यहाँ है स्पष्ट नहीं है; लेकिन मेरा अनुमान है कि आप उस ऑब्जेक्ट पर विधियों को कॉल कर रहे हैं जिन्हें स्वयं const के रूप में घोषित नहीं किया गया है और इस प्रकार const ऑब्जेक्ट संदर्भ द्वारा उपयोग करने योग्य नहीं हैं।

1

मुझे यकीन नहीं है क्योंकि मैं कोई विशेषज्ञ सी ++ प्रोग्रामर नहीं हूं, लेकिन क्या आपके फ़ंक्शन getRect() और घोषित कॉन्स पर हैं? यदि नहीं, लेकिन आप जानते हैं कि आप उनका उपयोग किस तरह से करते हैं, तो आप अभी भी अपने प्रारंभिक डेटा संदर्भ से कॉन्स्ट को हटाने के लिए const_cast का उपयोग कर सकते हैं।

उदाहरण यहाँ देखें: http://docs.oracle.com/cd/E19422-01/819-3690/Cast.html

या स्कॉट Meyers उत्कृष्ट सी ++ - किताबें Effective C++ और More Effective C++। उनमें से कम से कम एक में स्थिरता के बारे में एक वस्तु है।

इस तरह के
1

मैं सोच रहा हूँ लाइनों अवैध हैं:

links_ = new QList<QGraphicsLineItem*>(*links); 

points_ = new QList<QGraphicsEllipseItem*>(*points); 

कि links और points में पारित में संकेत के रूप में परिभाषित नहीं कर रहे हैं, लेकिन निर्धारित मान। आदेश कोड संकलन करने के लिए, आप शायद या तो उन्हें इस

const QList<QGraphicsLineItem*>* links 

तरह परिभाषित या, बजाय उन्हें इस

links_ = new QList<QGraphicsLineItem*>(&links); // don't actually do this 

की तरह उपयोग करने के लिए हालांकि बाद एक संभवतः एक रन-टाइम बग है, जरूरत है क्योंकि आप एक अस्थायी मूल्य के पते तक पहुंच रहे हैं, जो फ़ंक्शन बॉडी के बाद मर जाता है।

जब तक क्यूलिस्ट एक गहरी प्रतिलिपि का उपयोग नहीं करता है, तो आपका ऐप बहुत दुर्घटनाग्रस्त हो सकता है।

+0

धन्यवाद। आपने मुझे 2 और बग ट्रैक करने में मदद की है! – Extrakun

0
links_ = new QList<QGraphicsLineItem*>(*links); 

यह संभवतः कानूनी हो सकता है यदि * ऑपरेटर QList वर्ग के लिए ओवरलोड हो गया है, हालांकि मुझे नहीं लगता कि यह है।यद्यपि ऊपर वर्णित अनुसार, आप शायद

links_ = new QList<QGraphicsLineItem*>(links); 

वास्तविक कन्स्ट्रक्टर के बारे में क्या करने की कोशिश कर रहे हैं।

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

कॉन्स्टनेस से निपटने के दौरान याद रखने की एक बात यह है कि कॉन्स की गारंटी नहीं है। किसी वस्तु की दृढ़ता को दूर करने के लिए संरचनाएं "const_cast" जैसी मौजूद हैं। एक कॉन्स ऑब्जेक्ट होने और कॉन्स्ट फ़ंक्शंस का उपयोग अन्य डेवलपर्स को इंगित करने में सहायक होता है कि कोड को ऑब्जेक्ट को नहीं बदला जाना चाहिए, न कि इसे बदल नहीं सकता है। फर्क देखें?

void bar(const Foo& f) { 
    f.setX(5); // compile error, f is const 
    Foo &f2 = const_cast<Foo&>(f); 
    f2.setX(5); // compiles just fine 
} 

उपयोगी बात यह है कि वस्तु को बदलने के लिए अनजाने में प्रयास संकलक त्रुटियों में परिणाम होगा, एक निर्धारित प्रोग्रामर आसानी से इन सुरक्षाओं को नाकाम कर सकते हैं।

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