2011-01-08 14 views
0

たとえば、関数内に新しいオブジェクトを作成し、その参照を返すにはどうしたらいいですか?C++で参照を返す方法

私は、プライベートに 'int num'フィールドを持つIntClassがあるとします。だから私は、関数内のIntClassの新しい要素を作成し、そのオブジェクトの参照を返したいと思います。私はそのような何かをしようとしましたが、私は、私は、コンパイラ自体(ECLIPSE)からエラーを取得していないが、私は、コードをコンパイルするときにバイナリが削除されるようなことを行うときには、いくつかの理由から(違法と思われる:

IntClass* a = new IntClass(10); 
IntClass &ref = *a; 
return ref; 

どれをその後、参照を返すためにどのようなアイデア

EDIT:?それはそうここにそれを行うには、私が「欲しい」なぜそれがあなたのほとんどに明確ではないとしてC++にはガベージコレクション

を使用していること「を前提と」することができますされ完全な質問:

私はこのファイルを持っています(Not maデ・私が、編集することはできません):

poly_subtype.h

#ifndef POLY_SUBTYPE_H 
#define POLY_SUBTYPE_H 
#include <iostream> 
#include "cpu_add.h" 
using std::cout; 
using std::endl; 

//Deriving classes definition 
class IntClass; 
class DoubleClass; 

//The Virtual Number Class. IntClass and FloatClass will derive from this class. 
class Number { 
    public: 
     //return a Number object that's the results of x+this, when x is DoubleClass 
     virtual Number& addDouble(DoubleClass& x) = 0; 

     //return a Number object that's the results of x+this, when x is IntClass 
     virtual Number& addInt(IntClass& x) = 0; 

     //return a Number object that's the results of x+this, when x is either 
     //IntClass or DoubleClass 
     virtual Number& operator+(Number& x) = 0; 

     //Print the number stored in the object 
     virtual void print_number() = 0; 
}; 

class IntClass : public Number { 
    private: 
     int my_number; 
    public: 
     //Constructor 
     IntClass(int n):my_number(n) {} 

     //returns the number stored in the object 
     int get_number() {return my_number;} 

     //print the number stored in the object 
     void print_number() {cout << my_number << endl;} 

     //return a DoubleClass object that's the result of x+this 
     Number& addDouble(DoubleClass& x); 

     //return an IntClass object that's the result of x+this 
     Number& addInt(IntClass& x); 

     //return a Number object that's the result of x+this. 
     //The actual class of the returned object depends on x. 
     //If x is IntClass, then the result if IntClass. 
     //If x is DoubleClass, then the results is DoubleClass. 
     Number& operator+(Number& x); 
}; 

class DoubleClass : public Number { 
    private: 
     double my_number; 
    public: 
     //Constructor 
     DoubleClass(double n):my_number(n) {} 

     //returns the number stored in the object 
     double get_number() {return my_number;} 

     //Print the number stored in the object 
     void print_number() {cout << my_number << endl;} 

     //return a DoubleClass object that's the result of x+this 
     Number& addDouble(DoubleClass& x); 

     //return a DoubleClass object that's the result of x+this 
     Number& addInt(IntClass& x); 

     //return a DoubleClass object that's the result of x+this. 
     //This should work if x is either IntClass or DoubleClass 
     Number& operator+(Number& x); 
}; 

#endif 

と私は再び、私が書いていない、このファイルを(持っていると編集することはできません - と言いますこれらの関数は使用できますが、 '+'演算子は使用できません。

cpu_add.h:

Number& IntClass::addInt(IntClass& x); 
Number& IntClass::addDouble(DoubleClass& x); 
Number& IntClass::operator+(Number& x); 
Number& DoubleClass::addInt(IntClass& x); 
Number& DoubleClass::addDouble(DoubleClass& x); 
Number& DoubleClass::operator+(Number& x); 

:私の目標は、(あなたが上記のpoly_subtype.hに彼らの宣言と機能性を見つけることができます)、次の機能を実装することです

#ifndef CPU_ADD_H 
#define CPU_ADD_H 

double add_double_double(double a, double b) {return (a+b);} 
double add_int_double(int a, double b) {return ((double)(a)+b);} 
int add_int_int(int a, int b) {return (a+b);} 

#endif 

私はそれが今より明らかであることを願っています。例えば

いるAddInt

Number& IntClass::addInt(IntClass& x){ 
int num = add_int_int(my_number, x.get_number()); 
IntClass* a = new IntClass(num); 
IntClass &ref = *a; 
return ref; 
} 
+0

C++は、Eclipseは、コンパイラではありませんちなみにガベージコレクション – user550413

+0

を使用していること「を前提と」することができます。それはIDEです:) – UmmaGumma

+0

IntClassを参照渡ししてみませんか? void f(IntClass&ref) – anno

答えて

0

あなたは上記に書いたようにあなたが何かを行うことができますが、それは悪いかまちです。フリーストアにリソースが割り当てられている場合は、参照ではなくポインタを返す必要があります。さらに適切な種類のスマートポインタを使用してください。プロデューサがリソースを保持していない場合はstd::auto_pointer(またはそれ以上の場合はstd/boost::unique_ptr)、反対の場合はstd::shared_ptrになります。あなたのコード例は合法ですが、返された参照のコンシューマは、返された参照を処理する方法を知らない(できません)。

私はこのようなシナリオでは、オブジェクトへの一定の基準を返す想像することができます:

class Producer { 
std::shared_ptr<SomeObject> mObject; 

public: 
Producer() : mObject(new SomeObject) {} 

const SomeObject& GetObject() const { 
    return *mObject; 
} 

}; 

をただしかかわらず、特定の欠点を有している静的期間を持つオブジェクトへの参照を返すことができます - あなたは持っていません( )適切なオブジェクトのライフタイムを制御、例えば:。

SomeObject& GetSomeObjectSingletonReference() { 
static SomeObject sInstance; 
return sInstance; 
} 

乾杯、

ポール

+0

ええ、私はそれが普通ではないと言ったので、それは悪いスタイルだと分かっています。私はあなたの最後の提案を '静的なSomeObject'で試してみましたが、この関数でコードをコンパイルする前に自分のコードで同じようにしていましたが、バイナリが削除され、メインを実行しようとすると「バイナリが見つかりません。コード自体にエラーはありません。私はそれら2の間の接続が何であるか分かりませんが、コード内にこの関数を含める場合にのみ起こります。 – user550413

+0

バイナリが削除された理由がわかりませんが、これはIDE固有のものでなければなりません。参照で返すことについては、上記の第2のシナリオは「マイヤーのシングルトン」と呼ばれ、(a)プログラム内のオブジェクトのインスタンスを1回だけ必要とし、(b)ライフに関する特定の要件がない場合に便利ですオブジェクトの時間。たぶんあなたは何を達成しようとしているのかを書いておくべきです... –

+0

ありがとう、私は完全な "ゴール"と主な質問を編集しました。 – user550413

4

あなたのサンプルコードが起こるのを待って、メモリリークです。オブジェクトの終了時にオブジェクトを削除する責任は誰にありますか?参照(ポインタではなく)を返すという事実は、オブジェクトがヒープ上に割り当てられていることをさらにはっきりとさせます。ある時点で、誰かがdelete &obj;を行う必要があります。これはかなり邪悪です。

一般に、他の場所で参照されているオブジェクト(たとえば、クラスメンバまたはクラスメンバが指すヒープオブジェクト)への参照のみを返すようにしてください。具体的には、

IntClass myFunc() 
{ 
    ... 
    return IntClass(10); 
} 

、つまり返品による返品などがあります。

+0

私はC++がガベージコレクション。それは私が参照を返す理由ではありません - 私はそうするように頼まれました、そして、私はそれを行う方法がわかりません(通常あなたが私のコードでそうしない場合でも) – user550413

+1

@user:それは* stupidest *前提条件:) – fredoverflow

+4

@ user550413:C++にはガベージコレクタがないため、その前提で完全に壊れたコードになります。誰もここであなたが壊れたコードを書くのを助けるつもりはありません! –

3

なぜ最初に参照を返すのですか?参照の代わりに値を返すだけです。コンパイラは通常、それが問題であればコピーを最適化します。

参照してください効果的なC++、項目21

+0

それは私が参照を返す理由ではありません - 私はそうするように頼まれました、そして、私はそれを行う方法がわかりません(たとえあなたが私のコードでそうしていなくても)。また、上記のように、C++がガベージコレクションを使用することを「仮定」することが許されていたため、メモリリークは私の疑問ではありません。だから、コピーやポインタではなく、オブジェクトへの参照を返す方法はありますか? – user550413

+2

@user:誰があなたに依頼したのですか?あなたが本当に動的に割り当てられたオブジェクトへの参照を返すことを主張するなら、あなたはすでに自分の質問に答えを与えています。そのコードはうまくいくはずです。深刻なC++プログラマーが見たら、あなたの顔に嘔吐するでしょう。 – fredoverflow

+0

@FredOverflow:私は彼の名前に名前をつけることができました:Dしかし、私はコード内にこの関数を含めると(私はそれが間違っていて、C++にガベージコレクタがないことを知っています)バイナリは消えます。 Xさんの愚かな仮定のためだと言いますか? – user550413

1

ああ、わかりました。あなたは、 'this'オブジェクトaを変更して、そのオブジェクトへの参照を返す変更操作を実装することになっています。だから、のようだ:

Number& YourNumber::Add(const YourNumber& pX) { 
// do addition which mutates this... 
return *this; 
} 
関連する問題