2

[] 演算子を定義したいクラスがあります。このクラスは、シリアル パケットを (そのパケットを操作するための関連関数と共に) 保持します。ユーザーがこのようなことをできるようにしたいと思います...

MyClass packet;
uint8_t byte = packet[3];  // get third byte of packet

ユーザーがこれを行うのを防ぎたい...

packet[3] = 0xAA;  // this breaks encapsulation for my class :(

私は解決策を探していましたが、この宣言だけで十分かどうか疑問に思っていました (.cpp の関連コードと共に):

const uint8_t operator[](const std::size_t index) const;

これが機能することはかなり確信していますが、私のアプローチにはまだいくつかの不確実性があり、あなたが私の問題を解決してくれることを望んでいました.

  1. 参照ではなく値を返すだけで「OK」ですか?私が見たすべての例で参照が返されることを知っています。値を返すことは、操作の左側で「[]」を使用したくないという事実を回避するのに役立ちますか? 繰り返しますが、const はこれを妨げませんか?

  2. const関数は非constオブジェクトでも呼び出されますか? const バージョンの演算子と非 const 演算子が宣言されている例をいくつか見てきました。非 const は書き込みを許可しますが、const は読み取りのみを許可しますが、const オブジェクトに対してのみ呼び出されます。ここでの私の目標は、const 以外のオブジェクトでさえ、読み取りのみができるようにすることです。

  3. オペレーターからエラーを渡すクリーンな方法はありますか? 私の主な問題は、要求されているデータが私が持っているデータの範囲外にある可能性があることです。私が見たすべての例はアサートを使用していますが、ユーザーのオペレーターへの呼び出しがある種の陽気さを引き起こした場合に、必ずしもプログラムがクラッシュすることを望んでいません。また、返すバイトの値はすべて有効である可能性があるため、必ずしも特別なコードを返すことはできません。

いつものように、C プログラマーから OO C++ ウィザードへとゆっくりと (しかし確実に) 恐るべき移行を行っているので、あなたの助けに感謝します。

4

2 に答える 2

7
  1. はい、 のような小さな型の場合は、単純に値を返すだけで問題ありませんuint8_t。const 参照を返すことができ、const実際に誰もそれを介して書き込むことができなくなります。ただし、uint8_t値で返すような小さな型の場合は、より良い考えです。ところで、値で返す場合、戻り値の型は不要constになることに注意してください。

    const 参照を返すと、変更を防ぐのが難しい場合でも、呼び出し元のコードに、配列要素への潜在的に長寿命の参照とポインターを作成して格納する機能が与えられます。

    const uint8_t *byte = &packet[3];
    

    これが望ましくない場合は、値で返すとその機能もブロックされます。

  2. はい、const非 const オブジェクトに対して関数のバージョンが呼び出されます (非 const バージョンを提供していないと仮定します)。

  3. 例外は、その目的のために特別に導入されました。例外は、関数の宣言と仕様に影響を与えることなく、エラーが発生した場合の専用のフィードバック パスを提供します (つまり、エラーを返すために値を予約する必要はなく、その目的のためにパラメーターを導入する必要もありません)。

于 2013-07-06T21:46:56.287 に答える
1

で返して使用する場合

 packet[3] = 0xAA; 

packet[3] は変更可能な左辺値ではないため、コンパイラはエラーを返します。これは、代入の左側に表示できないことを意味します。

参照によって戻る場合、ユーザーは参照されているものを編集できます。const参照を使用して、変更を禁止できます。

参照アプローチには、値のコピーを回避できるという利点があります。これにより、operator[] の戻り値が大きい場合に効率/スペースが増加します。operator[] の戻り値のコピーを 1 つだけ存在させたい場合は、(const) 参照を使用する必要があります。

于 2013-07-06T21:48:11.717 に答える