了解运算符重载的效用

时间:2018-04-30 00:15:30

标签: c++ class operator-overloading

我一直在研究课程代码" DenseMatrix"旨在创建常规矩阵。

通过代码,我可以完全理解2到3件事 所以首先来看这个类的代码:

#include<iostream>
#include<complex>
#include<vector>
#include <cassert>

using namespace std ;

class DenseMatrix{
    typedef complex<double> Cplx;

private:
    int nr, nc;
    vector<Cplx> data;

public :
    DenseMatrix(const int& nr0, const int& nc0){
    nr = nr0; nc = nc0; data.resize(nr*nc,0);}

    DenseMatrix(const DenseMatrix& M){
    nr = M.nr; nc = M.nc; data.resize((M.data).size());
    for (int j=0; j<data.size(); j++) {data[j]=M.data[j];} }

    void operator=(const DenseMatrix& M){
    nr = M.nr ; nc = M.nc ; data.resize((M.data).size());
    for (int j=0; j<data.size() ; j++){data[j]=M.data[j];} }

    Cplx& operator () (const int& j ,const int& k) {
    assert(0<=j && j<nr && 0<=k && k<nc) ; return data[k+j*nc];}

    const Cplx& operator () (const int& j ,const int& k) const {
    assert(0<=j && j<nr && 0<=k && k<nc) ; return data[k+j*nc];}

    friend ostream& operator<<(ostream& o , const DenseMatrix& M){
    for ( int j =0; j<nr ; j++){ for ( int k=0; k<nc; k++){o << M(j,k) << "\ t " ;} o << endl ;}
    //return o ;}
};

首先,定义&#34; =&#34;的用途是什么?运算符,如果我们可以实际使用复制构造函数并获得相同的结果?

第二件事,如果我的理解是正确的,Cplx& operator ()将返回一个引用,这个引用实际上允许我们修改私有属性(matix的一个元素)。但是运算符const Cplx& operator () (const int& j ,const int& k) const的第二个定义是什么呢?它的实用性是什么?

谢谢!

3 个答案:

答案 0 :(得分:2)

  

首先,如果我们可以实际使用复制构造函数并获得相同的结果,那么定义“=”运算符的效用是什么?

因为您无法使用复制构造函数来获得相同的结果。复制构造函数是一个构造函数;它在构造矩阵时被使用。赋值运算符允许您分配已构造的矩阵。

  

第二件事,如果我的理解是对的,那么Cplx&amp; operator()将返回一个引用,这个引用实际上允许我们修改[矩阵的一个元素]。

     

但是运算符const Cplx& operator () (const int& j ,const int& k) const的第二个定义是什么呢?

该版本适用于const DenseMatrix的情况。想象一下,您使用了普通operator() - 您可以使用Cplx&来更改矩阵元素。但如果矩阵元素是const矩阵,则不允许更改矩阵元素。编译器不允许在const矩阵上使用第一个版本。

最后const(在{之前)说这个函数可以调用const DenseMatrix

答案 1 :(得分:1)

  

首先,定义&#34; =&#34;的用途是什么?如果我们可以实际使用复制构造函数并获得相同的结果吗?

他们是两种不同的野兽。复制构造函数允许您创建新对象作为现有对象的副本;赋值运算符允许您在现有对象上复制对象。所以:

DenseMatrix foo;
...
DenseMatrix bar(foo); // copy constructor
...
foo = bar; // assignment operator

差异很微妙但很重要:复制构造函数以pristine对象开头,而赋值运算符通常也要删除现有数据。

尽管如此,赋值运算符通常非常类似于析构函数+复制构造函数(大多数代码都是重复的),通常复制&amp;交换习惯用于最小化代码重复(同时实现其他有用的属性 - 例如流程中的强异常保证)。

  

但是运算符const Cplx& operator () (const int& j ,const int& k) const的第二个定义是什么呢?它的实用性是什么?

const重载是在类的const个实例上调用的重载(或通过const指针或引用访问的&#34;常规&#34;实例) ;在这种情况下,它们将返回与非const版本相同的数据,但作为const引用而不是普通引用,因此不允许调用者修改矩阵的数据,如根据调用它的对象的常量。

答案 2 :(得分:0)

引用不允许访问私有属性。这与使用裸露物体本身没什么不同。

具有两个版本的函数的惯用语,一个const而另一个不是,很常见。由于函数返回引用,它会从const函数返回const引用。