重载赋值和C++中的圆括号运算符

overload assignment and round bracket operator in C++

本文关键字:圆括号 运算符 C++ 赋值 重载      更新时间:2023-10-16

我想定义一个类myVector,它支持赋值operator=和括号访问,例如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。要解决这个问题,我只能想出两种解决办法。一种是定义类似double getValue(int i) const的东西,但这似乎很奇怪,因为添加了一些重复的代码。另一种是从()函数的签名中删除const,但这也是不可取的。我相信会有一个很好的解决方案,但我找不到。

正确的解决方案是"both"。包括运算符在内的成员函数可以在const-ness上重载(this指针实际上是一个参数,并参与重载解决)。

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

注意:对于非成员运算符,左边的对象不仅仅是一个参数,它也是一个参数。

对于运算符()的特殊情况,您应该只提供两个重载:

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

如果这是一个模板化的容器,第二个重载将返回一个const&,但如果它是double,则可以返回一个副本。

现在,建议您实现复制构造函数,然后实现一个简单的swap函数:

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

有了这两个工具,就可以使用operator=:的惯用实现

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

另一件事是,滚动自己的循环来复制向量是没有意义的,他们已经知道如何自己完成,所以_v = v._v;与循环具有相同的效果。