2010-11-25 4 views
1

誰かが私との違いを非常に小さな言葉で説明できますか?私はこれを理解していないし、私の現在のプロジェクトでは非常に混乱しています。私は何をしようとしていることは、このコードを修正です:リファレンスとポインタの違いは何ですか?

const Multinumber& Pairs::operator+(const Multinumber &rhs) const 
{ 
    const Pairs &_rhs = dynamic_cast<const Pairs &>(rhs); 
    Pairs toreturn(_rhs.X_value+X_value,_rhs.Y_value+Y_value); 
    return toreturn; //reference to local variable? fix this? 
} 

今私のコンパイラは、彼らが何らかの形であるため、これはローカル変数への参照ですが、それは私がポインタにtoreturnオンさせないことを私に語りました参考文献とは異なる。そして、抽象クラスのオブジェクトへの参照やポインタを保持することになっているsetクラスについても取り組んでいます。私は全く混乱している。どんな助けでも大歓迎です。

+1

http://stackoverflow.com/questions/57483/difference-between-pointer-variable-and-reference-variable-in-cあなたの場合、参照はエイリアスであり、いくつかのアドレスを参照しています。しかし、ローカルで作成された 'toreturn'を参照してから、' toreturn'の有効期間が終了しても関数の復帰時に参照を返そうとします。 – birryree

+0

あなたは常に 'static'を返すことができますが、それは良い考えではないようです... – erjot

答えて

1

あなたはそう、[OK]を:)非常に混乱しているようだん:ポインタが別の変数のアドレスを格納するだけの変数であり、基本的に

。例えば、私はiと呼ばれるintがあると、私はポインタpにそのアドレスを格納することができます:私は、それは(つまり、そのアドレスは、それが格納する変数)を指すものを変更したい場合は

int i = 23; 
int *p = &i; // p has type int* (pointer to int) and stores &i (the address of i) 

、Iちょうど*pに割り当ててください - これは指示されたことを示すのに使用される構文です。この場合、*piを指します。したがって:

*p = 9;  // sets i to 9 (since *p is i) 

私はすなわち

int j = 84; 
p = &j;  // store j's address in p, overwriting what was there before (i.e. i's address) 
*p = 18;  // sets j to 18 (since *p is now j) 

今、参照がわずかに異なっている、(すなわち、それは何か他のものを指して作る)ポインタを取り付け直しだけpに割り当てることができます。

int i = 23; 
int& r = i;  // r has type int& (reference to int) and refers to i 

注(コンパイラは物事を最適化開始特にとき、またはそれらがない場合もある)、それはプログラミングの観点から無関係だ参照はポインタの点でをを実施することができること:参照変数のエイリアスを作成します - ここで私たちにとって重要なのは、言語の仕組みです。

この場合、i)は、あなただけの操作を行います。

r = 9;  // sets i to 9 (since r is an alias for i) 

ポインタとは異なり、参照がを取り付け直すことはできません。上に示したように、rに代入すると、参照自体ではなく、(i)を参照しているものが変更されます。さらに、参照を再配置することはできないため、参照を直ちに初期化する必要があります。ポインタの場合はそうではありません。言い換えれば:

int *p;  // legal 
int& r;  // bad 

最後にもう一つの基本的な違いは、ポインタは、彼らが何を指していないことを示す、NULLすることができることです。これは単にアドレス0を含むことを意味します。参照は常に実際のオブジェクトを参照する必要があります。ポインタがNULLでない場合は、ポインターを使用してMaybe型を実装することができ、そうでない場合は別の処理を行うため、この違いが実装者にとって重要になります。彼らは参照で同じことをすることはできません。

ポインタと参照の関係は明らかです。今


、あなたのoperator+ - 加算演算子の目的は、2つのオブジェクトを追加し、その合計を表す新しいオブジェクトを返すことです。私は2次元ベクトル型を持っていたのであれば、私はそれのためにoperator+を書くかもしれません、次のように:あなたのコードで

Vec2 operator+(const Vec2& lhs, const Vec2& rhs) 
{ 
    return Vec2(lhs.x+rhs.x, lhs.y+rhs.y); 
} 

を、あなたは参照することにより、ローカルオブジェクトtoreturnを返すようにしようとしている - これは動作しません、なぜならオペレータの最後にはtoreturnが存在しなくなります。代わりにここで価値あるものに戻ってください。ちなみに、ポインタを返そうとした場合、同じ問題が発生します。そのコードで

Vec2* operator+(const Vec2& lhs, const Vec2& rhs) 
{ 
    Vec2 result(lhs.x+rhs.x, lhs.y+rhs.y); 
    return &result; // bad! 
} 

resultは、オペレータの端部に存在しなくなるので、あなたは、戻りポインタが無効な場所を指してしまうことになります。ボトムライン - このような状況では価値あるものに戻りましょう。

+0

ありがとう!とにかく、私の問題は、多態性を使用しているので、Multinumber型のオブジェクトを返さなければならないということです。基本クラスの演算子+は、Multinumberを返すように定義されています。コンプレックスはマルチナンバーを継承します。そしてMultinumberはバーチャルなので、私は価値よりもむしろ参考に戻らなければなりません。 –

2

まず、署名が間違っています。それは次のようになります。

Multinumber Pairs::operator+(const Multinumber &rhs) const; 

operator+は新しいオブジェクトではなく、どちらかの引数への参照を返す必要があります。

参考文献とポインタの違いについては、detailed questionがここにあります。それはすべての基本といくつかをカバーしています。

+0

実際にあなたの署名も間違っています。 'Multinumber operator +(const Multinumber&lhs、const Multinumber&rhs)'、あるいは 'const Multinumber operator +(const Multinumber&lhs、const Multinumber&rhs)'でなければなりません。 – wilhelmtell

+1

@wilhelmtell関数を宣言しました。@Andréが宣言したメソッド – Gaim

+0

@Gaimはいです。 'operator +()'は空き関数でなければならないからです。 – wilhelmtell

0

ポインタにオブジェクトがあるアドレスがいくつかあります。参照はポインタのエイリアスとしてあり、参照を逆参照する必要はありません。しかし、使い方は似ています - オブジェクトをコピーせず、起源でしか動作しません。

ローカル変数として変数toreturnがあります。これは、コンパイラがメソッドの最後にこのオブジェクトのデストラクタを生成することを意味します。あなたは破壊された物を返そうとしています。

関連する問題