2009-02-13 8 views
6

आज रात के लिए अंतिम प्रश्न, मैं वादा करता हूं। ये पॉइंटर्स मुझे गंभीर सिरदर्द दे रहे हैं।इन पॉइंटर्स को संदर्भित करते समय मैं गलती से ओवरराइटिंग कैसे कर रहा हूं?

मैं एक std :: सूची <Point> बहुभुज और एक std :: बहुभुज की सूची भी कहा जाता तरह परिभाषित किया गया है:

typedef std::list<Point> Polygon; 
typedef std::list<Polygon> PolygonList; 

// List of all our polygons 
PolygonList polygonList; 

मैं विधि बनाई नीचे से कोई (एक्स निकटतम प्वाइंट को हटाने के लिए प्रयास करने के लिए, वाई), मेरे बहुभुज सूची में मेरे सभी बहुभुजों की जांच।

void deleteNearestPoint(int x, int y) 
{ 
    y = screenHeight - y; 

    Polygon &closestPolygon = polygonList.front(); 
    Polygon::iterator closestPoint = closestPolygon.begin(); 

    float closestDistance = sqrt(pow(x - closestPoint->x, 2) + pow(y - closestPoint->y, 2)); 

    // Search PolygonList 
    PolygonList::iterator listIter; 
    Polygon::iterator iter; 

    for(listIter = polygonList.begin(); listIter != polygonList.end(); listIter++) 
    { 
     Polygon &tempPolygon = *listIter; 

     for(iter = tempPolygon.begin(); iter != tempPolygon.end(); iter++) 
     { 
      const float distance = sqrt(pow(x - iter->x, 2) + pow(y - iter->y, 2)); 

      if (distance < closestDistance) 
      { 
       closestPolygon = *listIter; 
       closestPoint = iter; 
       closestDistance = distance; 
      } 
     } 

    } 

    closestPolygon.erase(closestPoint); 

    redraw(); 
} 

हालांकि, कहीं मेरे पास एक सूचक या संदर्भ चर मुझे खराब कर रहा है। यह कोड संकलित करता है लेकिन एक बहुत ही अजीब तरीके से कार्य करता है।

मैं एक डिबग बयान लिखा गया है और कहते हैं कि मैं बहुत तरह मेरे बहुभुज सूची में 3 बहुभुज देता है:

बहुभुज #: 0
प्वाइंट: (448, 43)
प्वाइंट: (469 , 177)
प्वाइंट: (374, 123)
बहुभुज #: 1
प्वाइंट: (295, 360)
प्वाइंट: (422, 350)
प्वाइंट: (315, 266)
प्वाइंट: (295, 360)
बहुभुज #: 2
प्वाइंट: (143, 202)
प्वाइंट: (301, 203)
प्वाइंट: (222, 100)
प्वाइंट: (143, 202)

अब, चलो मैं कोशिश करते हैं और यह एक x/y पास देने हटाएँ फ़ंक्शन का उपयोग 422 इंगित करने के लिए कहते हैं, 350 वांछित परिणाम होगा यह बस बहुभुज # 1 लेकिन इसके बजाय से उस बिंदु (422, 350) को हटाने मुझे यह मिलता है:

पॉलीगॉन #: 0
प्वाइंट: (295, 360)
प्वाइंट: (422, 350)
प्वाइंट: (315, 266)
प्वाइंट: (295, 360)
बहुभुज #: 1
प्वाइंट: (295, 360)
प्वाइंट: (315, 266)
प्वाइंट: (295, 360)
बहुभुज #: 2
प्वाइंट: (143, 202)
प्वाइंट: (301, 203)
प्वाइंट: (222, 100)
प्वाइंट: (1 43, 202)

यह हटाना था (422, 350) लेकिन यह भी क्या बहुभुज # 1 इसके बिंदु के हटाने से पहले था करने के लिए बहुभुज # 0 अधिलेखन की अजीब पक्ष प्रभाव पड़ता है।

मुझे पता है कि मैं अपनी विधि में गलत सूचक या संदर्भ का उपयोग कर रहा हूं। क्या कोई यह बता सकता है कि मैं संभवतः ऐसा कर रहा हूं जो इसका कारण बन रहा है? मुझे लगता है कि ऐसा इसलिए है क्योंकि मेरा & निकटतम पॉलीगॉन को संदर्भ के रूप में घोषित किया गया है, लेकिन अगर मैं इसे किसी अन्य चीज़ के रूप में सेट करने का प्रयास करता हूं तो मुझे संकलन त्रुटियां मिलती हैं।

+0

एक के रूप में, और उम्मीद है कि कुछ शैक्षिक मूल्य के साथ: (मैं कोड का परीक्षण नहीं किया है) कुछ इस तरह करने के लिए फिर से लिखने का प्रयास करें वर्ग दूरी के साथ काम कर आप महंगा sqrt की बचत होगी() कहते हैं। इसके अलावा, पाउ() काफी महंगा है; चूंकि आप केवल पूर्णांक का उपयोग कर रहे हैं, तो आप अपने स्वयं के वर्ग() फ़ंक्शन को लिखने से बेहतर हैं। – Thomas

उत्तर

4

अन्य उत्तर ने बताया है क्या त्रुटि के कारण। एक सामान्य सलाह के रूप में मैं फ़ंक्शन तर्कों को छोड़कर संदर्भों का उपयोग न करने का सुझाव दूंगा। अर्थशास्त्र भ्रमित कर रहे हैं, ऐसे किसी भी व्यक्ति के लिए जो आपके कोड को पढ़ने का प्रयास करेगा। एक तरफ

void deleteNearestPoint(int x, int y) 
{ 
    y = screenHeight - y; 

    PolygonList::iterator closestPolygon = polygonList.begin(); 
    Polygon::iterator closestPoint = closestPolygon->begin(); 

    float closestDistance = sqrt(pow(x - closestPoint->x, 2) + pow(y - closestPoint->y, 2)); 

    // Search PolygonList 
    PolygonList::iterator listIter; 
    Polygon::iterator iter; 

    for(listIter = polygonList.begin(); listIter != polygonList.end(); listIter++) 
    { 
     for(iter = listIter->begin(); iter != listIter->end(); iter++) 
     { 
      const float distance = sqrt(pow(x - iter->x, 2) + pow(y - iter->y, 2)); 

      if (distance < closestDistance) 
      { 
       closestPolygon = listIter; 
       closestPoint = iter; 
       closestDistance = distance; 
      } 
     } 

    } 

    closestPolygon->erase(closestPoint); 

    redraw(); 
} 
+0

अच्छा जवाब डेन वैन डेर मेर – mmcdole

+0

हाँ, धन्यवाद। मेरे पास कई अच्छे उत्तर थे लेकिन मैं आपको इस कोड उदाहरण में कुछ अन्य चीजों को दिखाने के लिए भी सराहना करता हूं। दूसरे लूप को फिर से शुरू करने के लिए पहले इटरेटर के पॉइंटर का उपयोग करने की तरह, आदि एक आकर्षण की तरह काम किया। – KingNestor

3

आप एक संदर्भ के लिए नहीं सौंप सकते।
सी ++ में संदर्भों और सी # और संदर्भों में संदर्भों के बीच यह मुख्य अंतर है। एक बार जब आप किसी ऑब्जेक्ट के साथ संदर्भ चर प्रारंभ करते हैं, तो वह चर उस ऑब्जेक्ट के लिए उपनाम बन जाता है। संदर्भ चर को असाइन करना मूल ऑब्जेक्ट को असाइन करने के बराबर है। इसे ध्यान में रखकर, इस लाइन:

closestPolygon = *listIter; 

मतलब है कि आप वर्तमान एक के साथ पहले से पाया निकटतम बहुभुज को अधिलेखित कर रहे हैं। यह आपके द्वारा प्राप्त होने वाले परिणाम के अनुरूप भी है। मेरा सुझाव है कि आप इस विधि के संदर्भ के बजाय पॉइंटर्स का उपयोग करें।

इसके अलावा, जैसा किसी और के द्वारा बताया गया है, pow(... , 2) का उपयोग कर बेहद बेकार है। बेहतर अभी तक कुछ इस तरह लिखना:

x = a - b; 
xsquare = x * x; 

संपादित करें: संकेत के साथ इस लेखन ऐसा ही कुछ के साथ शुरू होगा:

void deleteNearestPoint(int x, int y) 
{ 
    y = screenHeight - y; 

    Polygon *closestPolygon = &polygonList.front(); 
    Polygon::iterator closestPoint = closestPolygon.begin(); 
+0

क्या आप थोड़ा विस्तार कर सकते हैं? मैंने पॉइंटर्स को सब कुछ बदलने की कोशिश की है और असफल रहा है। – KingNestor

+0

पाउ (..., 2) कम से कम सी ++ भूमि में ठीक है। यह एक ही चीज़ से संकलित होता है क्योंकि (फ्लोट, int) और (डबल, int) के लिए एक अधिभार है। – MSN

+0

@MSN, यहां तक ​​कि, शायद आपके पास अभी भी फ़ंक्शन कॉल का ओवरहेड है। – shoosh

6

दुर्भाग्य से, आप rebind नहीं कर सकते हैं एक संदर्भ, यानी, इस लाइन:

closestPolygon = * listIter;

*listIter से closestPolygon की प्रतिलिपि बनाएगा, *listIter पर रिफ़र्न्स को पुनर्विचार नहीं करेगा।

संपादित करें: आप जो चाहते हैं उसे करने के लिए, आपको 10 के बजाय PolygonList::iterator का उपयोग करना चाहिए और तदनुसार कोड समायोजित करना चाहिए।

2
closestPolygon = *listIter; 

बजाय वस्तु संदर्भ द्वारा बताया पर ऑपरेटर =() फोन करेंगे, तो यह दूसरे के साथ पहली बहुभुज ऊपर लिख देगा।

बजाय सूचक के रूप में closestPolygon घोषित (जो कर सकते हैं इसकी घोषणा के बाद भी विभिन्न वस्तुओं की ओर इशारा)

Polygon *closestPolygon = &(polygonList.front()); 
... 
closestPolygon = &(*listIter); 
1

मैं अपने प्रश्न पहले से ही उत्तर दिया गया है देखते हैं - मैं में मेरी 2 सेंट फेंक देंगे और सुझाव देते हैं कि आप डुप्लिकेटिंग कोड को सहेजने के लिए पॉइंट की एक विधि दूरी बनाएं।

जैसा कि अन्य ने कहा है कि आप स्क्वायरडिस्टेंस (एक्स, वाई) विधि भी चाह सकते हैं यदि इससे आपके लिए जीवन आसान हो जाएगा।

यदि आप फ़ंक्शन कॉल के ओवरहेड के बारे में चिंतित हैं तो या तो इनलाइन किया जा सकता है।

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

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