Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

クラス内のオブジェクト(クラス・構造体)を関数で返したもののpublicメンバに対して代入を行う

スポンサードリンク


なんともややこしい表現ですがこういうことです。
もう一度タイトルですが、
クラス内のオブジェクト(クラス・構造体)を関数で
返したもののpublicメンバに対して代入を行う

な… 何を言ってるのか わからねーと思うが
おれも何を言っているのかわからなかった…

#include <iostream>

using namespace std;

struct Foo
{
    Foo()
        : x_(10) { }
    int x_;
};

class Bar
{
private:
    Foo foo_;
public:
    Bar() { }
    //Foo getFoo() const // ... A
    //Foo getFoo()       // ... B
    Foo& getFoo()        // ... C OK
    {
        return foo_;
    }
};

int main()
{
    Bar bar;
    cout << bar.getFoo().x_ << '\n';

    // AとBの場合
    // g++  エラー: using temporary as lvalue [-fpermissive]
    // VC++ error C2106: '=' : 左のオペランドが、左辺値になっていません。
    // Cの場合 OK
    bar.getFoo().x_ = 20;
    cout << bar.getFoo().x_ << '\n';
    return 0;
}

まぁ冷静に考えればそうだよねという話。
ちなみにAとBの場合でエラーになった時に、
えーいでこんなことをやると値が変わらないので注意。
そりゃそうだ。

#include <iostream>

using namespace std;

struct Foo
{
    Foo()
        : x_(10) { }
    int x_;
    // セットしたいから追加したよ(*´Д`)!
    void setX(int x)
    {
        x_ = x;
    }
};

class Bar
{
private:
    Foo foo_;
public:
    Bar() { }
    Foo getFoo() const
    {
        return foo_;
    }
};

int main()
{
    Bar bar;
    cout << bar.getFoo().x_ << '\n';
    bar.getFoo().setX(20);
    cout << bar.getFoo().x_ << '\n';
    return 0;
}

コンパイルは通りますが、
20をセットしたつもりでも10になります。