了解运算符重载的效用
Understanding utility of an 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 ;}
};
第一件事是,如果我们实际上可以使用复制构造函数并获得相同的结果,那么定义"="运算符的效用是什么?
第二件事,如果我的理解是正确的,Cplx& operator ()
将返回一个引用,这个引用实际上将允许我们修改私有属性(matix的一个元素(。但是运算符的第二个定义const Cplx& operator () (const int& j ,const int& k) const
是做什么的呢?它的效用是什么?
谢谢!
第一件事是,如果我们实际上可以使用复制构造函数并获得相同的结果,那么定义"="运算符的效用是什么?
因为不能使用复制构造函数来获取相同的结果。复制构造函数是构造函数;当您构造矩阵时会使用它。赋值运算符允许您赋值到已构造的矩阵。
第二件事,如果我的理解是正确的,Cplx&运算符((将返回一个引用,这个引用实际上将允许我们修改[矩阵的一个元素]。
但是运算符的第二个定义
const Cplx& operator () (const int& j ,const int& k) const
有什么作用呢?
该版本适用于您有const DenseMatrix
的情况。想象一下,你使用了普通的operator()
- 你会得到一个可以用来改变矩阵元素的Cplx&
。但是,如果矩阵是const
矩阵,则不允许更改矩阵元素。编译器不允许在const
矩阵上使用第一个版本。
最后一个const
(在{
之前(说这个函数可以调用const DenseMatrix
。
第一件事是,如果我们实际上可以使用复制构造函数并获得相同的结果,那么定义"="运算符的效用是什么?
它们是两种不同的野兽。复制构造函数允许您创建一个新对象作为现有对象的副本;赋值运算符允许您将对象复制到现有对象上。所以:
DenseMatrix foo;
...
DenseMatrix bar(foo); // copy constructor
...
foo = bar; // assignment operator
区别是微妙的,但很重要:复制构造函数从一个原始对象开始,而赋值运算符通常也必须摆脱现有数据。
尽管如此,鉴于赋值运算符通常与析构函数 + 复制构造函数非常相似(大多数代码都是重复的(,通常使用 copy & swap 习惯用法来最小化代码重复(同时实现其他有用的属性 - 例如过程中的强异常保证(。
但是运算符的第二个定义
const Cplx& operator () (const int& j ,const int& k) const
是做什么的呢?它的效用是什么?
const
重载是通过类的const
实例(或通过const
指针或引用访问的"常规"实例(调用的重载;在这种情况下,它们将返回与非const
版本相同的数据,但作为const
引用而不是纯引用,因此不允许调用方修改矩阵的数据, 根据调用它的对象的恒定性。
引用不允许访问私有属性。这与使用裸对象本身没有什么不同。
一个函数有两个版本的习惯用语,一个const
,一个不是,这是很常见的。由于该函数返回引用,因此它从const
函数返回const
引用。
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 重载运算符new[]的行为取决于析构函数
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 在 myVector 类中重载运算符 + 时出错
- 为什么常量词在重载运算符中不与 ostream 对象一起使用<<?
- 如何在 cpp 中重载运算符 +=?
- C++ 如何重载 [] 运算符并进行函数调用
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 重载运算符有地址吗?
- 如何迭代重载运算符 [] 的类?
- 重载运算符与添加问题
- 模板基类中的重载运算符
- 如何调用用于重载运算符"<<"的 friend 函数?
- 在 C++17 中的命名空间和子命名空间中重载运算符是不明确的
- 重载运算符<<采用谷歌 C++ 风格
- C++ 如何正确重载 + 运算符
- cout (<<) 重载运算符不打印减去的矩阵
- 如何在 c++ 中重载运算符 + 以便能够 whrite c_str = "smth" + c_str;
- 重载运算符*以获取对另一个类的实例的引用