2017-09-14 10 views
1

は、私が必見に新しいAの感謝を生成する、のがメインコードでAとB新ポインタを参照にキャストしなければならない、私は2つのクラスを持っている

class A: 
{ 
    public: 
    //Some functions 

    A *getNewA() const; 

    private: 
    //some attributes 
} 

class B: 
{ 
    public: 
    //Some functions 
    private: 
    A &reftoA; 
} 

それらを呼びましょうA :: getNewA()メソッド。

A *A::getNewA() 
{ 
    A *newA = new A; 
    return newA; 
} 

OK:そして、このクラスBここで

に書かれたように、B :: reftoAにA :: getNewA()メソッドがされて行かなければなりません。だから今、私はこれがあったはずと思った(パラメータとしての参照を取る)B機能

B::foo(A &paramA) 
{ 
    reftoA = *(paramA.getNewA()); 
} 

ではA.へ参照である、getNewAを呼び出し、reftoAに結果を保存したいですしかし、それはしません。 逆参照の場合、reftoAは常にこのオブジェクトを取得し、新しい割り当てられたオブジェクトは取得しません。

のがより明確にし、ここで結果

A * A::getNewA() 
{ 
    A *newA = new A; 
    std::cout << "New pointer " << newA << std::endl; 
    std::cout << "this pointer" << this << std::endl; 

    return A; 
} 

void B::foo(A &paramA) 
{ 

    reftoA = *(paramA.getNewA()); 
    std::cout << "new generated pointer " << &reftoA << std::endl; 
} 

は、出力の一つであるのは、出力に機能を変更してみましょう:

New pointer : 004FFAEC 
this pointer: 0069D888 
New generated pointer : 0069D888 //Expected : 004FFAEC 

私はあることをこの「新しい生成されたポインタ」を得ることができませんA :: getNewA()はメモリを割り当てた後に新しいポインタと同じものを返します。もちろん、参照に格納するためにポインタを逆参照することでいくつかの点があると思います。 私は参照が既存のオブジェクトで使用されていることを知っています。たぶん新しいオブジェクトA :: getNewA()は、期待通りに動作しないためにメモリを割り当てるべきです。

私が代わりにBで参照ポインタを使用することができ

:: FOO()、私は知っているが、私はできない私はrefrenceとポインタについて何かを誤解していますが、私はないと思う

何を知っている。

すべてのヘルプは非常にはい、あなたが何かを誤解している

+2

待ちを使用することができますへの参照を再割り当てしたい場合は? 'return A'?それはどのように構築されますか?あなたに私たちを見せるために、[最小、完全で、かつ証明可能な例](http://stackoverflow.com/help/mcve)を作成してみてください。 –

+0

また、メモリリークがあります。あなたは 'getNewA'によって返されたポインタを破棄します(実際には' newA'を返すと仮定します)。 –

+0

最後に、あなたの問題の原因となる可能性のあるもの:*参照を再割当てすることはできません。あなたがやっているのは、*オブジェクト*に*を割り当てることです。あなたは効果的に 'reftoA.operator =(*(paramA。' –

答えて

1

を高く評価しました。

getNewA()がポインタを返しています。それはスマートなポインタではない、あなたはそれらを調べたいと思う、それは私が問題について言いたいことだ。

ポインタを返すときは、このポインタへの参照を保持する必要があります。それ以外の場合は、ポインタを削除できなくなり、メモリリークが発生します。したがって、あなたはどこかにA* a = A::getNewA()を持っていなければなりません。そして、後でそれが不要になったらdelete a;

Aへの参照を渡す必要がある場合は、foo(*a)を実行するとポインタを逆参照し、ポインタを参照しているオブジェクトへの参照を渡すことができます。

要約すると、すべての新しいコードでは、スマートポインタ。それらを使用しないという言い訳はありません。

サイドノート:コード例には他にもいくつか問題があります。 getNewAなどは静的ではありませんでした。私はあなたの理解の実際の例としてコードを取り上げ、実際の例ではありません。

編集:例を再読み込みすると、getNewAは意図的に非静的です。私はこの質問が実際にはXYの問題だと思います(つまり、あなたはあなた自身を強制した質問をしていますが、実際の問題ではありません)。私はこれがポインタと参照の誤解を解決することを願っています。

4

問題は、参照を再割り当てできないことです。参照されるオブジェクトの値のみを変更することができます。

だから、クラスB

のコンストラクタの初期化子リストの参照を初期化する必要があなたのコードにタイプミスがあることを考慮してください

A*A::getNewA() 
{ 
A *newA = new A; 
std::cout << "New pointer " << newA << std::endl; 
std::cout << "this pointer" << this << std::endl; 

return A; 
^^^^^^^^^ 
} 

スニペット私はあなたが意味を考えます

A*A::getNewA() const 
       ^^^^^ 
{ 
A *newA = new A; 
std::cout << "New pointer " << newA << std::endl; 
std::cout << "this pointer" << this << std::endl; 

return newA; 
^^^^^^^^^^^ 
} 

検証可能な完全な例を常に提供してください。ここで

は実証プログラム

#include <iostream> 

class A 
{ 
public : 
    //Some functions 

    A* getNewA() const 
    { 
     A *newA = new A; 
     std::cout << "New pointer " << newA << std::endl; 
     std::cout << "this pointer" << this << std::endl; 

    return newA; 
    } 

private : 
    //some attributes 
}; 

class B 
{ 
public : 
    B(const A& a) : reftoA(*a.getNewA()) 
    { 
     std::cout << "&reftoA " << &reftoA << std::endl; 
    } 
private : 
    A& reftoA; 
}; 

int main() 
{ 
    A a; 

    B b(a); 

    return 0; 
} 

その出力であるあなたがNew pointer&reftoAの値が他のそれぞれ同じである見ることができるように

New pointer 0x2b392afbec20 
this pointer0x7ffd287ad0af 
&reftoA 0x2b392afbec20 

です。それがより明確にプログラムの出力が

r = y; 

がオブジェクトを参照するための参照を強制するものではありませんでした

x = 20 
y = 20 
r = 20 

&x = 0x7ffd88ad47a8 
&y = 0x7ffd88ad47ac 
&r = 0x7ffd88ad47a8 

このステートメントは非常に単純な例

#include <iostream> 

int main() 
{ 
    int x = 10; 
    int y = 20; 

    int &r = x; 

    r = y; 

    std::cout << "x = " << x << std::endl; 
    std::cout << "y = " << y << std::endl; 
    std::cout << "r = " << r << std::endl; 

    std::cout << std::endl; 

    std::cout << "&x = " << &x << std::endl; 
    std::cout << "&y = " << &y << std::endl; 
    std::cout << "&r = " << &r << std::endl; 

    return 0; 
} 

を考えるようにするに

y。参照されたオブジェクトxの値を再割り当てしました。

参照の作成時に参照を初期化する必要があります。

+0

ありがとう!参照を再割り当てすることができなかったことを理解した後(私にとっては今の論理に見える)私はあなたのようなものを書くと思っていました。しかし、あなたはそれを良くしました、私は今よく理解しています。ご回答いただきありがとうございます。参照の仕組みを理解することは私にとって有益です。 – frankee

+0

@frankeeまったくありません。どういたしまして。:) –

0

あなたはgetNewA方法 -

A* A::getNewA() 
{ 
    A *newA = new A; 
    return A; // you are returning A and not newA 
} 

にポインタを返すされていないと、あなたが何を、std::reference_wrapper

class B : 
{ 
public : 
void foo(A& paramA) { 
    reftoA = *(paramA.getNewA()); 
} 

private : 
std::reference_wrapper<A> reftoA; 
} 
関連する問題