2008-11-19 11 views
9

मेरे पास आकार का एक सार आधार वर्ग है जिसे सर्कल और आयत दोनों व्युत्पन्न होते हैं, लेकिन जब मैं वीएस 2005 में निम्न कोड निष्पादित करता हूं तो मुझे त्रुटि मिलती है डीबग दावा विफल हो जाता है। उसी समय मैंने किसी भी वर्गवेक्टर इटेटरेटर dereferencable

अभिव्यक्ति: वेक्टर इटरेटर को अस्वीकार्य नहीं किया गया है, इसके लिए कारण क्या है।

vector<Shape*> s1; 
    s1.push_back(new Circle(point(1,2),3)); 
    s1.push_back(new Circle(point(4,3),5)); 
    s1.push_back(new Rectangle(point(1,1),4,5)); 

    vector<Shape*> s2(s1); 
    reverse(s1.begin(),s1.end()); 

    (*find(s1.begin(),s1.end(),new Circle(point(1,2),3)))->move(point(10,20)); 

उत्तर

12

सरल:

  • खोज के बाद से विफल रहता है अपने नव निर्मित सर्किल *
  • एक असफल खोज अंत इटरेटर जो deferencable के रूप में पकड़ा नहीं है देता है आकार की तुलना के साथ वेक्टर में नहीं पाया जा सकता एक डीबग निश्चय के

की तरह आप चाहते हैं यह काम करने के लिए के लिए, आप आकार की तुलना करने की क्या ज़रूरत है, आकार नहीं *

+०१२३५१६४१०

जैसा कि अन्य उत्तरों में बताया गया है, boost::ptr_vector यह हासिल करने का एक आसान तरीका है।

+0

और आकार सूचक की तुलना में आकार वस्तुओं की तुलना करने के लिए boost :: ptr_vector का उपयोग करें। यह आपको सामान्य एल्गोरिदम का अधिक स्वाभाविक रूप से उपयोग करने की अनुमति देता है। –

6

जैसा @ दाऊद पियरे पता चलता है: लगता है मूल्य आधारित: यह एक सूचक (जैसे 0x0F234420) है कि करने के लिए new Circle(point(1,2),3) आपने अभी बनाया सूचक के बराबर होती है के लिए iterators की रेंज में लग रहा है। चूंकि यह एक नई वस्तु है, यह वहां नहीं होगी।

आप find_if का उपयोग कर ऑपरेटर के साथ इसका उपयोग कर सकते हैं जो पॉइंटर द्वारा संदर्भित वस्तुओं की तुलना करता है।

हालांकि, मानदंड आकार के प्रकारों के बीच अंतर करने में सक्षम होना चाहिए।

class Shape { 
public: 
    //amongst other functions 
    virtual bool equal(const Shape*) const = 0; 
}; 

class Circle : public Shape { 
public: 
    bool equal(const Shape* pOther) const { 
     const Circle* pOtherCircle = dynamic_cast<const Circle*>(pOther); 
     if(pOtherCircle == NULL) return false; 
     // compare circle members 
    } 
}; 

class Rectangle : public Shape { 
public: 
    bool equal(const Shape* pOther) const { 
     const Rectangle* pOtherR = dynamic_cast<const Rectangle*>(pOther); 
     if(pOtherR == NULL) return false; 
     // compare rectangle members 
    } 
}; 



Shape* pFindThis = new Circle(point(1,2),3); 
vector<Shape*>::const_iterator itFound = find_if(s1.begin(),s1.end(), 
    bind1st(mem_fun(&Shape::equal), pFindThis))); 
delete pFindThis; //leak resolved by Mark Ransom - tx! 

if(itFound != s1.end()) { 
    (*itFound)->move(point(10,20)); 
} 
+0

क्या यह किया जाता है जब दूसरा पैरामीटर bind1st हटा देता है? यदि नहीं, तो आपके पास मेमोरी रिसाव है। मुझे लगता है कि आप बस एक स्थानीय अस्थायी चाहते हैं। –

+0

आप बिल्कुल सही हैं। – xtofl

2

यह boost :: ptr_vector का उपयोग करने का एक अच्छा कारण है।

यह न केवल इस तथ्य को संभालता है कि आपकी वस्तुओं को नष्ट करने की आवश्यकता है।
xtofl @: आप वर्चुअल विनाशक भूल गए हैं।

लेकिन यह सदस्यों को पॉइंटर्स के बजाय संदर्भ लौटने से वस्तुओं की तरह दिखता है। यह आपको अपने 'बराबर' फ़ंक्शन में पॉइंटर्स के साथ खेलने के बजाए मानक एल्गोरिदम का अधिक स्वाभाविक रूप से उपयोग करने की अनुमति देता है (जो बहुत सी सी ++ जैसा है)।

#include <boost/ptr_container/ptr_vector.hpp> 
#include <iostream> 

class Shape 
{ 
    public: 
     ~Shape() {} 
     bool operator==(Shape const& rhs) const 
     { 
      if (typeid(*this) != typeid(rhs)) 
      { 
       return false; 
      } 

      return this->isEqual(rhs); 
     } 
    private: 
     virtual bool isEqual(Shape const& rhs) const = 0; 
}; 

class Circle: public Shape 
{ 
    public: 
     Circle(int r) 
      :radius(r) 
     {} 
    private: 
     virtual bool isEqual(Shape const& r) const 
     { 
      Circle const& rhs = dynamic_cast<Circle const&>(r); 
      return radius == rhs.radius; 
     } 
     int radius; 
}; 
class Rectangle: public Shape 
{ 
    public: 
     Rectangle(int h,int w) 
      :height(h) 
      ,width(w) 
     {} 
    private: 
     virtual bool isEqual(Shape const& r) const 
     { 
      Rectangle const& rhs = dynamic_cast<Rectangle const&>(r); 
      return (height == rhs.height) && (width == rhs.width); 
     } 
     int height; 
     int width; 
}; 


int main() 
{ 

    boost::ptr_vector<Shape> data; 

    data.push_back(new Circle(5)); 
    data.push_back(new Circle(6)); 
    data.push_back(new Rectangle(7,4)); 

    boost::ptr_vector<Shape>::iterator f; 
    f = find(data.begin(),data.end(),Circle(6)); 

    std::cout << "Find(" << (f - data.begin()) << ")" << std::endl; 


} 
+0

यह ऑपरेटर == पर भरोसा करने के लिए थोड़ा खतरनाक प्रतीत होता है यह सत्यापित करने के लिए कि आकृतियों को कॉल करने से पहले आकार समान हैं। मैं देखना चाहता हूं कि अंदर की जांच खुद ही है, जैसा कि xtofl किया था। –

+0

मैं इसे 'ऑपरेटर ==' में पसंद करता हूं इस तरह कोड को दोहराया नहीं जाता है। आप इसे क्यों चाहते हैं? नोट आकार एक शुद्ध आभासी है, कोई उदाहरण नहीं हो सकता है। मुझे नहीं लगता कि आपको लगता है कि यह डरावनी क्यों है? –

+0

मुझे बेस क्लास में टाइपिंग टाइपिंग के बारे में एक संदेह है। वास्तव में इसकी आवश्यकता क्यों है? क्योंकि सही करने के लिए कॉल Isqual फ़ंक्शन को पॉलीमोर्फिज्म के कारण रनटाइम पर हल किया जाता है। – Poorna

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