【问题标题】:overload assignment and round bracket operator in C++C++中的重载赋值和圆括号运算符
【发布时间】:2012-03-30 21:06:30
【问题描述】:

我想定义一个 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,但这也是不可取的。我相信会有一个很好的解决方法,但我找不到它。

【问题讨论】:

  • 为什么这么复杂 - 你可以说_v = v;,或_v.swap(v);
  • 那些圆括号叫“小括号”,算子叫“函数调用算子”
  • 这几乎与之前的问题完全相同。 stackoverflow.com/questions/5762042/…My answer 也适用于此。

标签: c++ function-call-operator


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    如果这是一个模板容器,第二个重载将返回一个const&amp;,但鉴于它是一个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; 与你的循环具有相同的效果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-30
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 2012-04-22
      • 2015-06-01
      • 2011-01-27
      • 2011-05-31
      相关资源
      最近更新 更多