マトリックスなどの大きなオブジェクトがあり、このオブジェクトを何らかの方法で変更する機能を提供したいと考えていました(マトリックスの場合、マトリックスを反転したい場合があります)。
反転機能を実装する最良の方法は何ですか?
次の 4 つのオプションが思い浮かびます。
- 自分自身を反転するメンバー関数 Matrix::invert() を持つことができます。
- メンバー関数は、新しい逆行列 (のようなもの
std::string::substr
)を構築できます。 - invert は、参照を取得して変更する非メンバー関数である可能性があります。
void invert(matrix& m)
- invert は、行列を値で受け取り、反転してから返す非メンバー関数である可能性があります。
matrix invert(matrix m)
ユーザーが元のマトリックスを保持したい場合、元のマトリックスは変更されないため、現在、4 番目のオプションが最善のように思えます。
auto m = matrix{};
auto m2 = invert(m);
また、逆行列のみが必要な場合は、次のことを行うことができます:
auto m = matrix{};
auto m2 = invert(move(m));
または
auto m = invert(matrix{})
(新しく構築された行列が逆に移動され、変更され、rvo'd または m に移動されるため、これは効率的なはずです)
しかし、これは、クラスの表現に影響を与える操作はメンバー関数として実装する必要があるという考えに反します。matrix& matrix::invert()
したがって、理想的には、親行列が右辺値で呼び出されている場合は親行列を変更しますが、左辺値で呼び出されている場合はそのままにして新しい行列を返すメンバー関数を実装する方法が必要です。これは正しいアプローチでしょうか?そして、それはどのように実装できますか?
別のオプションは、元のメンバーを変更するメンバーと、パラメーターが右辺値 (移動される場合) か左辺値 (この場合) に応じて「正しいことを行う」非メンバーを実装することです。コピーが作成されます)。これにはまだ 2 つの欠点があります。
- より多くのコード、今では 2 つの反転関数があるため
- m.invert() を言いたいかもしれませんが、元の行列を変更したくないので、連鎖は厄介です。
例: https://gist.github.com/mfaizan/6631482
ありがとう!