C++ 理解运算符重载的效用

C++ 理解运算符重载的效用,c++,class,operator-overloading,C++,Class,Operator Overloading,我一直在编写一个类“DenseMatrix”的代码,该类旨在创建规则矩阵 通读代码,有两三件事我不太明白。 首先,这是这个类的代码: #include<iostream> #include<complex> #include<vector> #include <cassert> using namespace std ; class DenseMatrix{ typedef complex<double> Cplx; pr

我一直在编写一个类“DenseMatrix”的代码,该类旨在创建规则矩阵

通读代码,有两三件事我不太明白。
首先,这是这个类的代码:

#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 ;}
};
#包括
#包括
#包括
#包括
使用名称空间std;
类密度矩阵{
typedef复合Cplx;
私人:
北卡罗来纳州国际天然气公司;
矢量数据;
公众:
DenseMatrix(常数int&nr0,常数int&nc0){
nr=nr0;nc=nc0;data.resize(nr*nc,0);}
DenseMatrix(常数DenseMatrix&M){
nr=M.nr;nc=M.nc;data.resize((M.data.size());

for(int j=0;j引用不允许访问私有属性。这与使用裸对象本身没有什么不同


一个函数有两个版本的习惯用法,一个是
const
,另一个不是。由于函数返回一个引用,它从
const
函数返回一个
const
引用。

引用不允许访问私有属性。这与处理裸对象本身没有什么不同

一个函数有两个版本的习惯用法,一个是
const
,另一个不是。由于函数返回一个引用,因此它从
const
函数返回一个
const
引用

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

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

DenseMatrix foo;
...
DenseMatrix bar(foo); // copy constructor
...
foo = bar; // assignment operator
区别很微妙,但很重要:复制构造函数从一个原始对象开始,而赋值操作符通常也必须除去现有数据

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


但是操作符的第二个定义,constcplx&operator()(constint&j,constint&k)const
是做什么的呢?它的用途是什么

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

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

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

DenseMatrix foo;
...
DenseMatrix bar(foo); // copy constructor
...
foo = bar; // assignment operator
区别很微妙,但很重要:复制构造函数从一个原始对象开始,而赋值操作符通常也必须除去现有数据

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


但是操作符的第二个定义,constcplx&operator()(constint&j,constint&k)const是做什么的呢?它的用途是什么

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

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

因为您不能使用复制构造函数来获得相同的结果。复制构造函数是一个构造函数;它在您构造矩阵时使用。赋值运算符允许您对已构造的矩阵进行赋值

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

但是操作符的第二个定义,
constcplx&operator()(constint&j,constint&k)const
做了什么

该版本适用于具有
常量DenseMatrix
的情况-您将获得一个
Cplx&
,您可以使用它来更改矩阵元素。但是,如果它是
常量
矩阵,则不允许您更改矩阵元素。编译器不允许在
常量
矩阵上使用第一个版本

最后一个
const
(在
{
之前)表示可以调用
const DenseMatrix
函数

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

因为您不能使用复制构造函数来获得相同的结果。复制构造函数是一个构造函数;它在您构造矩阵时使用。赋值运算符允许您对已构造的矩阵进行赋值

第二件事,如果我的理解是正确的,Cplx&operator()将返回一个引用,这个