1

私は参照の背後にあるものを本当に理解していないと思います。それらについてもっと学びたいと思います。

数値シミュレーションの基本的な線形代数を実行する数学「ベクトル」クラスを作成しています。外部ライブラリをもう使用しないと確信する前に、私は Eigen を使用していました。私の問題はかなり簡単です:

  • ベクトルを宣言し、型の 3 つのコンポーネントを設定しますScalar(これらは double です)。演算子をオーバーロードすると、ベクトルを使って計算できますが、これは私の質問の範囲を超えています。
  • Eigen で使用されていたように、関数呼び出し演算子 () を介してオブジェクトの i 番目のコンポーネントにアクセスしたい:myVector(0) = 0.0 ;またはScalar d = myVector(0)+1.0 ;

私の参照の理解によると、このソリューションは機能するはずです:

class mtnVector {
public:
    typedef double Scalar;
    Scalar  data [3];
    (setters, math, etc...)
    inline Scalar & operator() (const int i) const {
        return data[i] ; 
    }
};

しかし、g ++は、私がそれを実装する方法が気に入らないと言い、参照でs ***を確認します: Vector.h:185: error: invalid initialization of reference of type ?double&? from expression of type ?const double?

私の観点から非常に奇妙なのは、データを含む配列がScalar * dataクラスの構築時に ( new 演算子を使用して) 動的に設定される場合、コードが正常にコンパイルされることです。しかし、データホルダーを動的に設定する意味がわかりません。

関数呼び出し演算子をオーバーロードするために const を使用する必要もありませんが、受け入れます。

4

1 に答える 1

2

あなたoperator()は宣言されてconstいます。これは、関数を呼び出してもオブジェクトが変更されてはならないことを意味します。この関数は、非const参照によってこのオブジェクトのメンバーを返します。これにより、呼び出した人は誰でもoperator()オブジェクトの内部を変更できます。明らかにこれはばかげているので、コンパイラはそれを許可しません。メンバー関数からメンバーへの参照を返す場合は、constその参照を作成する必要がありますconst

inline const Scalar& operator() (const int i) const {
    return data[i] ; 
}

関数のバージョンconstと非バージョンの両方を提供することをお勧めします。一方はaを返し、もう一方はaを返します(これは、標準ライブラリコンテナーが行う方法です)。constconst Scalar&Scalar&

これに使いたいoperator()のは不思議に思えます。あなたの表現myVector(0)はより自然に見えるでしょう、それはあなたが代わりにmyVector[0]オーバーロードすることによって達成することができます。operator[]

また、外部ライブラリを使用すべきではないと確信した人は無視する必要があります。特にEigenは、非常に成熟しており、徹底的にテストされたライブラリです。本当に正当な理由がない限り、それを使用する必要があります。

于 2013-02-08T15:45:55.453 に答える