2012-01-18 73 views
19

我有一個名爲Object的類,它存儲了一些數據。如何在C++中通過引用返回類對象?

我想通過參考使用這樣的函數返回它:

Object& return_Object(); 

然後,在我的代碼,我會這樣稱呼它:

Object myObject = return_Object(); 

我已經寫的代碼這個和它編譯。但是,當我運行代碼時,我始終得到一個seg錯誤。什麼是通過引用返回類對象的正確方法?

+1

不應該myObject是一個referrence? – 2012-01-18 17:28:52

+0

你可以在這裏找到答案: http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c – MOHRE 2017-02-25 05:32:21

+0

你可以在這裏找到方法:http://stackoverflow.com/問題/ 3350385 /如何返回一個對象在c – MOHRE 2017-02-25 05:34:16

回答

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(); 

如果返回的對象具有比功能的更大的範圍內。例如,如果你有一個封裝類的地方,你可以使用它。如果您在函數中創建一個對象,請使用指針。如果要修改現有對象,請將其作爲參數傳遞。

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; Object outsideObj = mc.return_Object;' 如果我然後修改'outerObj'的屬性,那實際上是否修改了封裝在'mc'內的'myObj'? – livefree75 2017-02-22 16:06:44

+0

Object outsideObj = mc.return_Object();將引發實例'outsideObj'的複製構造。它現在是一個單獨的實例,並且修改一個會影響另一個實例,這取決於複製構造函數的實現方式。 – UmNyobe 2017-02-23 11:21:37

1

那麼,它可能不是一個非常漂亮的代碼解決方案,但它真的很漂亮,在你的函數接口中。而且它也非常有效。如果第二個對你更重要(例如,你正在開發一個庫),這是理想的。

訣竅是這樣的:

  1. 甲線A a = b.make();在內部轉換爲A的構造,即,如果你寫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; 
}