2

operator=割り当てとブラケット アクセスの両方をサポートするクラス myVector を定義したいと考えていますmyclass(1) = 0.5。以下のダミーの例を参照してください

class myVector
{
public:
    vector<double> _v;
    myVector(unsigned int size) : _v(size, 0) { }

    double& operator()(int i)
    {
        return _v[i];
    }

    unsigned int size() const { return _v.size(); }

    myVector& operator=(const myVector& v)
    {
        _v.resize(v.size());
        for(int i=0;i<v.size();i++)
            _v[i] = v(i);
    }
}

()は定数関数として定義されていないため、このコードはコンパイルできません。などの直接代入を有効にしたいからですmyvector(1) = 2。この問題を解決するには、2 つの解決策しか考えられません。1 つは sth を定義することです。のようですdouble getValue(int i) constが、重複したコードが追加されているため、これは奇妙に思えます。もう 1 つはconst、関数の署名から削除する()ことですが、これも望ましくありません。良い回避策があると確信していますが、見つけることができません。

4

2 に答える 2

2

正解は「両方」です。演算子を含むメンバー関数は、const-ness でオーバーロードできます (thisポインターは実質的にパラメーターであり、オーバーロードの解決に関与します)。

double& operator()(int i) { return _v[i]; }
double operator()(int i) const { return _v[i]; }

注: 非メンバ オペレータでは、左側のオブジェクトは単なるパラメータではなく、パラメータです。

于 2012-03-30T21:11:31.093 に答える
0

operator() の特定のケースでは、2 つのオーバーロードを提供する必要があります。

double& operator()( int i ) { return _v[i]; }
double operator()( int i ) const { return _v[i]; } // [1]

これがテンプレート化されたコンテナーの場合、2 番目のオーバーロードは を返しますがconst&、それが であることを考えるとdouble、コピーを返すことは問題ありません。

推奨事項として、コピー コンストラクターを実装してから、単純なswap関数を実装できます。

void myVector::swap( myVector & lhs ) {
   _v.swap( lhs._v );
}

これら 2 つのツールを配置すると、次の慣用的な実装を使用できますoperator=

myVector& myVector::operator=( myVector rhs ) { // by value
   swap( *this, rhs );
   return *this;
}

もう 1 つのことは、ベクターをコピーするために独自のループをロールするのは意味がないということです。それらは自分でそれを行う方法を既に知っているため_v = v._v;、ループと同じ効果があります。

于 2012-03-30T22:08:05.740 に答える