1. ホーム
  2. c++

[解決済み] C++のゲッターとセッターの書き方

2022-02-17 15:18:58

質問

セッターやゲッターを書く必要がある場合、以下のように記述します。

struct X { /*...*/};

class Foo
{
private:
    X x_;

public:
    void set_x(X value)
    {
        x_ = value;
    }
    X get_x()
    {
        return x_;
    }
};

しかし、私はこのようなことを聞いたことがあります。 Javaスタイル のセッターとゲッターの書き方について、C++スタイルで書くようにとのこと。さらに、それは不完全であり、間違っているとさえ言われました。どういうことでしょうか?C++でセッターとゲッターを書くにはどうしたらいいのでしょうか?


ゲッターやセッターの必要性が正当化されると仮定します。 . 例えば、セッターで何らかのチェックを行うかもしれませんし、ゲッターだけを書くかもしれません。

ゲッターとセッターは必要ない、という意見が多く聞かれます。私はここで言われていることのほとんどに同意しますが、それでもなお、このようなメソッドをイディオムに書く方法を知っておくことの必要性を主張します。一見するとセッターやゲッターに見えないかもしれませんが、そうであり、少なくともその書き方のパターンが適用されるのです。

例)。

  • ベクターの大きさを取得する。読み取り専用にする必要があるため、データメンバを公開しないようにします。

  • ゲッターとセッターは、単にデータ・メンバーを公開するだけでよいわけではありません。配列の要素を取得したり設定したりすることを考えてみてください。そこにはロジックがあり、単にデータメンバーを公開することはできませんし、そもそも公開すべきデータメンバーは存在しません。そもそも公開するデータメンバが存在しないのです。それでもゲッターとセッターのペアは避けられないのです。

    class Vector
    {
        void set_element(std::size_t index, int new_value);
        int get_element(std::size_t index);
    };
    
    

    C++の慣用的なゲッターとセッターの書き方を知っていると、上のような書き方ができるようになります。 get_element / set_element をC++のイディオムで表現しています。

解決方法は?

標準ライブラリには2種類のプロパティがあり、ここでは「アイデンティティ指向」と「バリュー指向」に分類しています。どちらを選ぶかは、システムがどのように Foo . どちらがより正しいというわけではありません。

アイデンティティ重視

class Foo
{
     X x_;
public:
          X & x()       { return x_; }
    const X & x() const { return x_; }
}

ここでは 参照 を、その下にある X これにより、コールサイトの両側で、他方によって開始された変更を観察することができます。また X メンバが外から見えるのは、おそらくその正体が重要であるためと思われる。一見すると、プロパティの "get"側しかないように見えるかもしれませんが、これは X は代入可能です。

 Foo f;
 f.x() = X { ... };

価値観重視

class Foo
{
     X x_;
public:
     X x() const { return x_; }
     void x(X x) { x_ = std::move(x); }
}

ここでは コピー X メンバを受け取り コピー で上書きする。どちらかの側での後の変更は伝搬しません。おそらく、私たちが気にするのは x この場合