2012-01-18 8 views
19

मेरे पास ऑब्जेक्ट नामक एक वर्ग है जो कुछ डेटा संग्रहीत करता है।सी ++ में संदर्भ द्वारा कक्षा वस्तु को वापस कैसे करें?

मैं इस तरह एक समारोह का उपयोग कर संदर्भ द्वारा इसे वापस करना चाहते हैं:,

Object& return_Object(); 

फिर, मेरे कोड में मैं इसे इस तरह कहेंगे:

Object myObject = return_Object(); 

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

+1

मेरा ऑब्जेक्ट रेफरेंस नहीं होना चाहिए? –

+0

आप यहां जवाब पा सकते हैं: http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c – MOHRE

+0

आप यहां तरीकों को ढूंढ सकते हैं: http://stackoverflow.com/ प्रश्न/3350385/कैसे-टू-रिटर्न-ए-ऑब्जेक्ट-इन-सी – MOHRE

उत्तर

35

आप शायद उस वस्तु को वापस कर रहे हैं जो ढेर पर है। यही है, return_Object() शायद इस तरह दिखता है:

Object& return_Object() 
{ 
    Object object_to_return; 
    // ... do stuff ... 

    return object_to_return; 
} 

यदि यह आप क्या कर रहे हैं, तो आप भाग्य से बाहर हो रहा है - object_to_return क्षेत्र से बाहर चला गया है और return_Object के अंत में विलुप्त कर दिया गया है, तो myObject संदर्भित करता है एक अस्तित्वहीन वस्तु के लिए। आपको या तो मूल्य से वापस लौटने की आवश्यकता है, या Object को व्यापक क्षेत्र में घोषित किया गया है या new एड ढेर पर घोषित किया गया है।

13

आप संदर्भ के द्वारा केवल गैर-स्थानीय वस्तुओं को वापस कर सकते हैं। विनाशक ने कुछ आंतरिक सूचक, या जो कुछ भी अवैध कर दिया हो सकता है।

मूल्य लौटने से डरो मत - it's fast!

18

आप केवल

 Object& return_Object(); 

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

class MyClass{ 
     private: 
     Object myObj; 

     public: 
     Object& return_Object() { 
      return myObj; 
     } 

     Object* return_created_Object() { 
      return new Object(); 
     } 

     bool modify_Object(Object& obj) { 
      // obj = myObj; return true; both possible 
      return obj.modifySomething() == true; 
     } 
    }; 
+0

लेकिन क्या होता है यदि मेरे कॉलिंग कोड में मैं कहता हूं: 'MyClass mc; ऑब्जेक्ट के बाहर ऑब्जेक्ट = mc.return_Object; ' यदि मैं फिर 'बाहरी ओबीजे' के गुणों को संशोधित करता हूं जो वास्तव में' myObj' को संशोधित करता है जो 'mc' के अंदर encapsulated है? – livefree75

+0

ऑब्जेक्ट के बाहर ऑब्जेक्ट = mc.return_Object(); उदाहरण के बाहर 'बाहरी ओबीजे' की एक प्रति निर्माण को उकसाएगा। अब यह एक अलग उदाहरण है, और क्या किसी को संशोधित करना दूसरे पर निर्भर करेगा कि कॉपी कन्स्ट्रक्टर को कैसे लागू किया गया है। – UmNyobe

1

ठीक है, यह शायद कोड में वास्तव में एक सुंदर समाधान नहीं है, लेकिन यह आपके कार्य के इंटरफ़ेस में वास्तव में सुंदर है। और यह भी बहुत ही कुशल है। यह आदर्श है यदि दूसरा आपके लिए अधिक महत्वपूर्ण है (उदाहरण के लिए, आप एक पुस्तकालय विकसित कर रहे हैं)।

चाल यह है:

  1. एक लाइन A a = b.make(); आंतरिक रूप से एक के एक निर्माता है, अर्थात जैसे कि आप A a(b.make()); लिखा था में बदल जाती है।
  2. अब b.make() को कॉलबैक फ़ंक्शन के साथ एक नई कक्षा का परिणाम होना चाहिए।
  3. यह पूरी चीज केवल कक्षाओं द्वारा बिना किसी टेम्पलेट के ठीक से संभाली जा सकती है।

मेरा न्यूनतम उदाहरण यहां दिया गया है। केवल main() देखें, क्योंकि आप देख सकते हैं कि यह आसान है। आंतरिक नहीं हैं।

गति के दृष्टिकोण से: Factory::Mediator वर्ग का आकार केवल 2 पॉइंटर्स है, जो 1 और अधिक नहीं है। और यह पूरी चीज में एकमात्र वस्तु है जिसे मूल्य द्वारा स्थानांतरित किया जाता है।

#include <stdio.h> 

class Factory { 
    public: 
    class Mediator; 

    class Result { 
     public: 
     Result() { 
      printf ("Factory::Result::Result()\n"); 
     }; 

     Result(Mediator fm) { 
      printf ("Factory::Result::Result(Mediator)\n"); 
      fm.call(this); 
     }; 
    }; 

    typedef void (*MakeMethod)(Factory* factory, Result* result); 

    class Mediator { 
     private: 
     Factory* factory; 
     MakeMethod makeMethod; 

     public: 
     Mediator(Factory* factory, MakeMethod makeMethod) { 
      printf ("Factory::Mediator::Mediator(Factory*, MakeMethod)\n"); 
      this->factory = factory; 
      this->makeMethod = makeMethod; 
     }; 

     void call(Result* result) { 
      printf ("Factory::Mediator::call(Result*)\n"); 
      (*makeMethod)(factory, result); 
     }; 
    }; 
}; 

class A; 

class B : private Factory { 
    private: 
    int v; 

    public: 
    B(int v) { 
     printf ("B::B()\n"); 
     this->v = v; 
    }; 

    int getV() const { 
     printf ("B::getV()\n"); 
     return v; 
    }; 

    static void makeCb(Factory* f, Factory::Result* a); 

    Factory::Mediator make() { 
     printf ("Factory::Mediator B::make()\n"); 
     return Factory::Mediator(static_cast<Factory*>(this), &B::makeCb); 
    }; 
}; 

class A : private Factory::Result { 
    friend class B; 

    private: 
    int v; 

    public: 
    A() { 
     printf ("A::A()\n"); 
     v = 0; 
    }; 

    A(Factory::Mediator fm) : Factory::Result(fm) { 
     printf ("A::A(Factory::Mediator)\n"); 
    }; 

    int getV() const { 
     printf ("A::getV()\n"); 
     return v; 
    }; 

    void setV(int v) { 
     printf ("A::setV(%i)\n", v); 
     this->v = v; 
    }; 
}; 

void B::makeCb(Factory* f, Factory::Result* r) { 
     printf ("B::makeCb(Factory*, Factory::Result*)\n"); 
     B* b = static_cast<B*>(f); 
     A* a = static_cast<A*>(r); 
     a->setV(b->getV()+1); 
    }; 

int main(int argc, char **argv) { 
    B b(42); 
    A a = b.make(); 
    printf ("a.v = %i\n", a.getV()); 
    return 0; 
} 
संबंधित मुद्दे