2012-01-18 12 views
19

Bazı verileri depolayan Object adında bir dersim var.C++ 'da referans olarak bir sınıf nesnesi nasıl iade edilir?

Böyle bir fonksiyonu kullanarak referans olarak iade etmek istiyorum: benim kodunda,

Object& return_Object(); 

Sonra böyle çağırır: Ben böyle bir kod yazdım

Object myObject = return_Object(); 

Bu ve derler. Ancak, kodu çalıştırdığımda sürekli olarak bir seg hatası alıyorum. Bir sınıf nesnesini referans olarak döndürmenin doğru yolu nedir?

+1

myObject bir başvuru olmamalıdır? –

+0

Burada cevabını bulabilirsiniz: http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c burada yollarını bulabilirsiniz – MOHRE

+0

: http://stackoverflow.com/ sorular/3350385/how-to-dönüş-bir-in-c nesne – MOHRE

cevap

35

Yığında olan bir nesneyi büyük olasılıkla iade ediyor olabilirsiniz. Yani return_Object() muhtemelen böyle görünüyor geçerli:

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

    return object_to_return; 
} 

bu size şans bitti, ne yaptığını ise - yani myObject eder, object_to_return kapsam dışında gitti ve return_Object sonunda tahrip olmuştur varolan olmayan bir nesneye. Ya değere dönmeniz veya daha geniş bir kapsamda bildirilen bir Object veya yığına new döndürülmeniz gerekir. döndürülen nesne işlevi daha büyük kapsamına sahipse

13

Yalnızca yerel olmayan nesneleri referans olarak gönderebilirsiniz. Yıkıcı bazı iç işaretçileri geçersiz kılabilir veya her neyse.

Değerleri geri çevirmekten korkmayın - it's fast!

18

Yalnızca

 Object& return_Object(); 

kullanabilirsiniz. Örneğin, kapsüllenmiş bir sınıfınız varsa bunu kullanabilirsiniz. İşlevinizde bir nesne oluşturursanız, işaretçileri kullanın. Mevcut bir nesneyi değiştirmek isterseniz, bunu bir argüman olarak iletin.

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

Ama çağıran kod diyorum, ne olur: 'Sınıfım mc; outsideObj = mc.return_Object Nesne; ' Sonra outsideObj' aslında' mc' içine kapsüllü olduğu 'myObj' değiştirmek gelmez' özelliklerini değiştirmek durumunda? – livefree75

+0

Nesne outsideObj = mc.return_Object(); Örneğin 'outsideObj' bir kopyası yapımını uyandıracak. Her biri ayrı bir örneğidir ve bir etkileyecek değiştirerek olsun diğer kopya yapıcısı nasıl uygulandığını bağlıdır. – UmNyobe

1

Bu, kodda gerçekten güzel bir çözüm olmayabilir, ancak işlevinizin arabiriminde gerçekten çok güzel. Ve ayrıca çok verimli. İkincisi sizin için daha önemli ise idealdir (örneğin, bir kütüphane geliştiriyorsunuz).

hile şudur:

  1. Bir çizgi A a = b.make(); içten A'nın bir yapılandırıcı yani oturum A a(b.make()); yazmış gibi dönüştürülür.
  2. Şimdi b.make(), geri arama işlevi olan yeni bir sınıfa neden olmalıdır.
  3. Bu her şey, şablonlar olmadan yalnızca sınıflar tarafından ele alınabilir.

İşte benim en küçük örneğim. Gördüğünüz gibi sadece main()'u kontrol edin. İçyapılar değil.

Hızın bakış açısından: Factory::Mediator sınıfının boyutu yalnızca 2 göstericidir, bu sayı 1'dir, ancak daha fazla değildir. Ve bu, değere göre aktarılan her şeydeki tek nesnedir.

#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; 
}