メインコンテンツへスキップ

Getter、Setterとは? 必要かどうか迷った場合に考えること

··1588 文字·4 分·
プログラミング Rust C++
著者
Admin
目次

クラスや構造体のメンバのpublic, privateとは
#

(クラスや構造体に関して)public、privateは多くの言語でクラスや構造体のメンバを別のコードから参照できるかどうかを意味する。

つまり、

class MyClass{
public:
    int a; // public
    int b; // public
private:
    int c; // private
    bool d; // private
};

というクラスがあった時、

int main(){
    MyClass x;

    int z = x.a; // OK publicなので アクセスできる
    bool e = x.d; // NG(コンパイルエラー) privateなのでアクセスできない!


    return 0;
}

のように別コードからMyClassの実体xを通してメンバ(フィールドとも呼ばれる)にアクセスできるかどうかということだ。

この例ではa, bはアクセスできるが、c, dはアクセスできない。

Getter、Setterとは
#

それぞれ、ゲッター、セッターと読む。

厳密な定義は知らないが、具体的にどんなもののことを言っているのかというと、

struct DeviceCommandBuffer {
    pub is_dummy_device: bool, // public

    buffer: Vec<u8>, // private
    priority: u32, // private

    // ...
}

impl DeviceCommandBuffer {
    pub fn buffer(&self) -> &[u8] {
        &self.buffer
    }

    pub fn set_priority(&mut self, new_priority: u32) {
        const MAX_PRIORITY:u32=0xffff;
        if MAXPRIORITY < new_priority {
            panic!();
            // もしくはResultを返すとか
        }
        self.priority = new_priority;
    }

    pub fn priority(&self) -> u32 {
        self.priority
    }

    // ...
}

のようなコードがあるとして、

getterは fn bufferfn priorityのようなクラスや構造体のメンバの値を取得する関数のことを指す。
setterは fn set_priorityのようなクラスや構造体のメンバに値をセットする関数のことを指す。

getter は 読み、setter は 書きだ。

Getter, Setterを実装すべきかどうか
#

考えられるうち、有用なパターンとしては、

  1. 完全にパブリックにする C++のpublic、Rustのpub
  2. プライベートにしてGetterのみを定義する
  3. プライベートにしてSetterのみを定義する
  4. プライベートにしてSetterとGetterを定義する
  5. 完全にプライペートにする C++のprivate、Rustではデフォルト

だ。

パブリックにするのであれば、ゲッターもセッターも迂回できてしまうので実装する必要はなくなる。

3のSetterのみについては俺の経験では実装を考えたことはない。
もしかしたらそういった状況があるのかもしれないが。

比較より、それぞれの利点や使いどころまとめたほうが良いと思ったのでそうする。

上のDeviceCommandBufferが先進的な自動医療手術で麻酔薬を投与する際に使われるコードだと仮定する。
麻酔を入れすぎると患者がホトケになると想定。
何を言いたいのかというとそのくらいの緊張感を持って考えるということ。

プライベートにしてGetterのみを定義する
#

ライブラリのユーザーなどが不用意に重要な変数を弄ってしまうことを防ぐことができる。

デバッグビルドにだけGetterに範囲チェックのassertionを入れてバグを見つける可能性を高めるなんてこともできる。
privateなのでassertionは必ず通ることになる。

Getterの関数名はget_xyz()xyz()が多い。(自分は後者のほうが好み。)

プライベートにしてSetterとGetterを定義する
#

これだったら完全にパブリックにしてしまえと言う人もいるが、setterで数値の範囲チェックなどの入力値の検証を行うこともできる。

もちろん、有効な値でしか生成できない構造体や型を定義してそれを利用してpublicにすることもできるが。

完全にプライペートにする
#

外に全く晒す必要のない変数はこれでok。

自分の場合、今のところは分からないという場合はprivateにしておいて必要になったらgetterを実装するなり、publicにするなりしている。

結論
#

絶対にこうしておけばおkなんてことはない。
状況に応じて決断しよう。

特にライブラリなどの使い回されるコードを書いている場合は、ユーザーが間違った使い方をしないようにしてあげると良いと思う。

(自分のプログラムでコアな部分を書いている時に迷って考えたのでまとめた。)

Related

Rustでティンクル☆くるせいだーすSBXの検証用ツールを実装した
··1666 文字·4 分
プログラミング Rust ゲーム
DolphinエミュレーターでスマブラXをプレイする際に曲を別に流せるようにする
··2566 文字·6 分
プログラミング スマブラX dolphin C++ toml miniaudio xtool
近況、進捗、就活、仕事のやめどき、今後の計画
··2301 文字·5 分
日記 学習 プログラミング 数学 wgpu 仕事 CG 数学 退職