首页 > 作文

C++中的运算符重载详解

更新时间:2023-04-04 16:46:09 阅读: 评论:0

目录
1、引例2、类中自动建立的函数3、重载赋值运算符解析总结

1、引例

class complex{private:    double real,image;public:    complex():real(0),image(0)  {}    complex(double r, double i) : real(r),image(i) {}    ~complex()  {}};int main(){    complex c1(1.2,2.3);    complex二字词组 c2(45,56);    complex c3;    c3 = c1.add(c2);           }

类非常简单,下面我们要讨论如何写一个什么地写add函数,使得两个对象的属性相加,返回一个新的对象。

第一种:

complex::complex add(const complex &c){    complex co;    co.real = this->real + c.real;    co.image = this->image + c.image;    return co;}

问题1:如何写出最节省空间的add函数?

第二种:

complex::complex add(const complex &c) const{    return complex(c.real + this->real, c.image + this.image);}

由于不需要改变调用对象的属性值,我们给this指针添加const 修饰。

分析过程如下:

问题2:为什么第一种方式不节省空间呢?

首先第一种的代码比较繁琐,并且在函数栈帧中又创建了一个对象(第3行)。并且函数类型是值传递类型(第6行),返回的是一个将亡值对象。那么整个add函数空间会产生两个对象,造成空间的浪费。

第二中代码创建的是无名对象,减少了一个co对象的创建,并且将无名对象直接作为将亡值对象传递给main函数中的c3。

问题3:我们能否将add函数改为引用类型,这样来减少将亡值对象的创建

complex::complex &add(const complex &c) const{    return complex(c.real + this->real, c.image + this.image);}

vs2019发现报错,不能返回引用对象:

我们进行分析:

问题4:我们能否将这个add函数名改为 + 运算符?

//complex::complex add(const complex &c) constcomplex::complex +(const complex &c) const {complex co;co.real = this->real + c.real;co.image = this->image + c.image;return co;}int main(){    ...    //c3 = c1.add(c2);      c3 = c1.+(c2);    //将原先add的地方改变为加号。    ...}        

这样使用,编译器又会报错,操作符不可作为一个有效的函数名来被使用

问题5:如何使 +预算符 作为函数名使用?

这就引出了今天的关键,函数运算符重载

在c++中,为了使操作符作为一个有效的函数名,我们在操作符前面添加一个operator

complex operator+(const complex &c) const {     return complex(c.real + this->real,c.image + this->image);}int main(){     complex c1(1.2,2.3);     complex c2(10,10);     complex c3;     c3 = c1 + c2;         //上面一行实际上是     //c3 = c1.operator+ (c2);     //c3 = operator+(&c1,c2);  //编译器还会经过一次编译}

前面几篇博客已经分析了第15行的由来,是将c1的地址传递给this指针,将c2作为形参c的别名传递给函数。

2、类中自动建立的函数

在c++中,如果我们定义一个类,它会给我们自动创建六个缺省函数

构造函数析构函数拷贝构造函数赋值函数普通对象的&(取地址符)的重载常对象的&(取地址符)重载

代码示例如下:

cl贪生怕死莫入此门ass object{public:    object()    {}//构造函数    ~object()   {}//析构函数    object(const object &obj)   {}//拷贝构造函数    object &operator=() {const object &obj} //赋值函数    {        return *this;    }        object *operator&()//普通对象的&(取地址符)的重载    {        return this;    }        const object *operator&() const//常对象的&(取地址符)重载    {        return this;    }};

汾河灌溉网然后,在c11标准下,又增添了两个缺省函数,这里不做深究:

移动构造函数移动赋值函数

3、重载赋值运算符解析

回到最初的例子:

class object{    int value;public:    object ()   {        cout << "create:" << this << endl;    }                  //普通构造函数    object (int x = 0):value(x) {cout << "create:" << this << endl;}  //缺省构造函数    ~object()                       //析构函数    {        cout << "~objcet() " << this << endl;    }    object(object &obj):value(obj.value)                 {        cout << "copy create:" << this << endl;    }    int & value()    {        return value; 吹口哨的歌   }    const int &value() const     {        return value;    }              object &operator=(const object& obj)        //此处加引用    {        this->value = obj.value;        return *this;       //this指针指向objb的地址。赋值函数结束后,objb不会被消亡,所以可以以引用返回    }    void operator=(const object& obj)       //赋值语句不可给this指针加const    {        this->value = obj.value;    }    };int main(){    object objx(0);    object objy(0);    objy = fun(objx);    cout << objy.value() << endl;    return 0;}

我们在34行添加一个等号运算符重载函数: void operator=(const object& obj)

此处不可添加const修饰this指针,因为需要使用this指针作为左值被修改。

问题6:void operator=(const object& obj) 只能用于 obja = objb,为什么不可以这样使用 obja = objb = objc;

我们逐一分析:

obja = objb = objc;//当调用等号运算符函数的时候。obja = objb.operator = (objc);obja = operator = (&objb,objc);//如果此处是调用的是 void operator=(const object& obj) ;//等号从右向左指向,我们不能把一个void 类型赋给一个obja对象类型。

我们将赋值运算符进行再次重载,丢弃 void 版本:

object &operator=(const object& obj)        //此处加引用{this->value = obj.value;return *this;       //this指针指向objb的地址。赋值函数结束后,objb不会被消亡,所以可以以引用返回}

这样就可以使用了。

我们接着上次的深入分析:

obja.operator=(operator=(&objb,objc));operator=(&obja,operator=(&objb,objc));

问题7:如果遇到obja = obja这种情况,如何赋值呢?

回答:对this指针和形参引用进行判断。

object &operator=(const object &obj){    if(this != &obj)    {        this->value = obj.value    }}

问题8:为什么函数是在栈区构建的,以引用返回打印的不是一个随机值?

运行程序,vs2012中,打印的是一个随机值。

vs2019打印的是一个正常值。

c));

> 问题7:如果遇到obja = obja这种情况,如何赋值呢?>> 回答:对this指针和形参引用进行判断。```cppobject &operator=(const object &obj){    if(this != &obj)    {        this->value = obj.value    }}

问题8:为什么函数是在栈区构建的,以引用返回打印的不是一个随机值?

运行程序,vs2012中,打印的是一个随机值。

vs2019打印的是一个正常值。

在win10系统中,vs2019与操作系统完全结合,安全性更高。当程序多次运行的时候,它的逻辑地址都不一样,这样做的好处是:当病毒入侵时,由于程序的逻辑地址是变化的,病毒不好寻找入侵的入口。

总结

到此这篇关于c++中的运算符重载详解的文章就介绍到这了,更多相关c++运算符重载内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

本文发布于:2023-04-04 16:46:07,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/3a1a12376544ea4f5d6f99229a7efc72.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:C++中的运算符重载详解.doc

本文 PDF 下载地址:C++中的运算符重载详解.pdf

标签:函数   赋值   对象   的是
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图