2012-01-18 8 views
19

私はいくつかのデータを格納するObjectというクラスを持っています。C++での参照によってクラスオブジェクトを返す方法は?

私はこのような機能を使用して参照することによってそれを返すしたいと思います:

Object& return_Object(); 

その後、私のコードでは、私はこのようにそれを呼び出します。

Object myObject = return_Object(); 

私のようなコードを書かれていますこれがコンパイルされます。しかし、私がコードを実行すると、私は一貫してseg faultを取得します。参照によってクラスオブジェクトを返す適切な方法は何ですか?

+1

myObjectは参照ではいけませんか? –

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

を使用することができます。たとえば、クラスがカプセル化されている場合に使用できます。関数内にオブジェクトを作成する場合は、ポインタを使用します。既存のオブジェクトを変更する場合は、引数として渡します。

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; ' ' outsideObj'のプロパティを変更すると、 'mc'の中にカプセル化された' myObj'が実際に変更されますか? – livefree75

+0

オブジェクトoutsideObj = mc.return_Object();インスタンス「outsideObj」のコピー構築を引き起こします。これは現在別のインスタンスになっており、コピーコンストラクターの実装方法に応じて変更するかどうかは変更されますか。 – UmNyobe

1

コードでは本当に美しい解決策ではないかもしれませんが、機能面では本当に美しいです。また、非常に効率的です。 2番目がより重要な場合(たとえば、ライブラリを開発している場合など)は理想的です。

トリックはこれです:

  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; 
} 
関連する問題