operator overloading(操作符重载,运算符重载)

所谓重载就是重新赋予新的意义,之前我们已经学过函数重载,函数重载的要求是函数名相同,函数的参数列表不同(个数或者参数类型)。操作符重载也叫运算符重载,顾名思义,运算符重载就是给运算符赋予新的意义,新的使命。

1、首先要说的是,c++中不允许用户自定义运算符,只允许程序员重载运算符。

2、那些运算符可以重载?c++中绝大部分与运算符允许重载,不能重载的运算符有5类,

(1) . (成员访问运算符)。(2).* (成员指针运算符)(3)::(域运算符)

(4)sizeof (长度运算符(5):?(条件运算符/三目运算符)

3、操作符重载的意义,由于c++中不允许用户自定义运算符,所以操作符重载可以满足用户自定义的类型之间的操作运算。比如对象之间的加减乘除等操作。

4、重载运算符的规则。

(1)、重载不能改变运算符运算对象的个数(即操作数的个数)

(2)、重载不能改变运算符的优先级。

(3)、重载不能改变运算符的结合性。

(4)、重载运算符的函数不能有默认的参数,否则就改变了运算符参数的个数,与前面第(3)点矛盾。

(5)、重载的运算符必须和用户定义的自定义类型的对象一起使用,其参数至少应有一个是类对象(或类对象的引用)。也就是说,参数不能全部是C++的标准类型,以防止用户修改用于标准类型数据的运算符的性质。

(6)、用于类对象的运算符一般必须重载,但有两个例外,运算符“=”和“&”不必用户重载。

         ① 赋值运算符(=)可以用于每一个类对象,可以利用它在同类对象之间相互赋值。(这样的拷贝是浅拷贝(logical copy),如果
     成员变量有指针的话,这样的拷贝会造成二次删除,如果要避免二次删除,那么就有必要重载 = 运算符了)

         ② 地址运算符&也不必重载,它能返回类对象在内存中的起始地址。

② *也不必重载,它能返回类对象在内存中的起始地址。

(7)、应当使重载运算符的功能类似于该运算符作用于标准类型数据时所实现的功能。

(8)、运算符重载函数可以是类的成员函数(如例10.2),也可以是类的友元函数,还可以是既非类的成员函数也不是友元函数的普通函数。


Eg:友元函数重载加减乘除(+ - * /)重载

#include<iostream>

#include<stdlib.h>

using namespace std;



class Complex

{

public:

    Complex(float r=0,float i =0):_r(r),_i(i)

        {

        }

        void print() const

        {

                cout<<" _r "<<_r<<" _i "<<_i<<endl;

        }

private:

        float _r;

        float _i;



friend const Complex operator+(const Complex & x,const Complex & y);

friend const Complex operator-(const Complex & x,const Complex & y);

friend const Complex operator*(const Complex & x,const Complex & y);

friend const Complex operator/(const Complex & x,const Complex & y);

friend ostream & operator<<(ostream & out,const Complex & y);

};

inline const Complex operator+(const Complex & x,const Complex & y)

{

        return Complex(x._r+y._r,x._i+y._i);

}

inline const Complex operator-(const Complex & x,const Complex & y)

{

        return Complex(x._r-y._r,x._i-y._i);

}

inline const Complex operator*(const Complex & x,const Complex & y)

{

        return Complex(x._r*y._r-x._i*y._i,x._r*y._i+x._i*y._r);

}

inline const Complex operator/(const Complex & x,const Complex & y)

{

        if(y._r==0 && y._i==0)

        {

                exit(1);

        }

        float den=y._r*y._r+x._i*y._i;

    return Complex((x._r*y._r+x._i*y._i)/den,(x._i*y._r-x._r*y._i)/den);

}

inline ostream & operator<<(ostream & out,const Complex & x)

{

        out<<" -r "<<x._r<<endl;

        out<<" _i "<<x._i<<endl;

        return out;

}



int main()

{

        Complex x(2,3),y(-1,3);

        cout<<" x is ";

        x.print();

        cout<<" y is ";

        y.print();



        (x+y).print();

        operator+(x,y).print();

        (x-y).print();

        operator-(x,y).print();

        (x*y).print();

        operator*(x,y).print();

        (x/y).print();

        operator/(x,y).print();





        cout<<"=================="<<endl;

        operator<<(cout,x);

        (cout<<x)<<"______________"<<endl;

        return 0;



}


成员函数 + - * / 操作符重载

Eg:c成员函数重载加减乘除(+ - * /)重载

#include<iostream>

#include<stdlib.h>

using namespace std;



class Complex

{

public:

        Complex(float r=0,float i =0):_r(r),_i(i)

        {

        }

        void print() const

        {

                cout<<" _r "<<_r<<" _i "<<_i<<endl;

        }

private:

        float _r;

        float _i;

public:

const Complex& operator+(const Complex & y);

const Complex& operator-( const Complex & y);

const Complex& operator*(const Complex & y);

const Complex& operator/(const Complex & y);

};

inline const Complex& Complex::operator+(const Complex & y)

{

        this->_r=_r+y._r;

        this->_i=_r+y._i;

        //(_r+y._r,_i+y._i)

        return (*this);

}

inline const Complex& Complex::operator-( const Complex & y)

{

        return Complex(_r-y._r,_i-y._i);

}

inline const Complex& Complex::operator*( const Complex & y)

{

        return Complex(_r*y._r-_i*y._i,_r*y._i+_i*y._r);

}

inline const Complex& Complex::operator/( const Complex & y)

{

        if(y._r==0 && y._i==0)

        {

                exit(1);

        }

        float den=y._r*y._r+_i*y._i;

        return Complex((_r*y._r+_i*y._i)/den,(_i*y._r-_r*y._i)/den);

}

int main()

{

        Complex x(2,3),y(-1,3);

        cout<<" x is ";

        x.print();

        cout<<" y is ";

        y.print();

        (x.operator+(y)).print();

        

        

        (x+y).print();

        cout<<" x is ";

        x.print();

        cout<<" y is ";

        y.print();

        return 0;



}


>> 输入操作符重载

Eg:>> 输入操作符重载

#include<iostream>

#include<stdlib.h>

using namespace std;



class Complex

{

public:

        Complex(float r=0,float i =0):_r(r),_i(i)

        {

        }

        void print() const

        {

                cout<<" _r "<<_r<<" _i "<<_i<<endl;

        }

private:

        float _r;

        float _i;



friend istream& operator>>(istream &in, Complex& x);

friend ostream& operator<<(ostream &out,const Complex&x);

};

istream& operator>>(istream &in, Complex& x)

{

        in>>x._r>>x._i;

        return in;

}

ostream& operator<<(ostream &out,const Complex&x)

{

        out<<" _r = "<<x._r<<endl;

        out<<" _i = "<<x._i<<endl;

        return out;

}

int main()

{

        Complex x(2,3),y(-1,3);

        x.print();

        Complex d;

        cin>>d;

        //operator>>(cin,x);

        x.print();

        return 0;



}

浅拷贝(logical
copy)  vs  深拷贝(physical copy)


//Eg:浅拷贝
#include<iostream>
#include<string.h>
#define MAX_CHAR 10
using namespace std; class Account
{
public:
Account(char* name="unknown",char* mr="Miss",float f=0.0)
{
title=new char[strlen(name)+1];
strcpy(title,mr);
strcpy(owner,name);
balance=f;
}
            //这里并没有实现深拷贝。只是一个普通的函数,但是这里的思想和重载操作符 = 是一样的,都是单独开辟一段新的             //空间,然后再进行拷贝。~~~~

	    void changetitle(char* newname)
{
if(strlen(newname)>strlen(title))
{
char* tmp=title;
title=new char[strlen(newname)+1];
strcpy(title,newname);
delete []tmp;
}
else
{
strcpy(title,newname); }
}
void changename(char* newname)
{
strcpy(owner,newname);
}
~Account()
{
delete []title;
title=NULL; }
private:
char* title;
char owner[MAX_CHAR];
float balance; friend ostream& operator<<(ostream & os,Account & b); };
ostream& operator<<(ostream & os,Account & b)
{
os<<"who:"<<b.title<<" "<<b.owner<<" "<<b.balance<<endl;
return os;
}
int main()
{
Account acc("zhanger gou","Mr",1000);
Account ac1;
cout<<acc;
cout<<ac1;
ac1=acc;
cout<<ac1;
cout<<acc;
ac1.changename("er gou");
cout<<acc;
cout<<ac1;
ac1.changetitle("Re");
cout<<acc;
cout<<ac1; return 0;
}

浅拷贝的两个问题:

1)、两个对象的指针指向同一块空间,改变其中一个,两个都改变。

2)、两个对象的指针指向同一块空间,不知道谁负责释放指向的空间,很容易造成二次删除。

重载操作符 = 

首先判断是不是自拷贝

第二步 删除指针指向的原来的空间

第三步 开辟新的空间

第四步 拷贝内容,注意的是要将所有内容都拷贝一遍,否则的话会遗漏,其他的会被赋值成默认值。

第五步 返回自身 *this

//Eg:深拷贝 
#include<iostream>
#include<string.h>
#define MAX_CHAR 10
using namespace std; class Account
{
public:
Account(char* name="unknown",char* mr="Miss",float f=0.0)
{
title=new char[strlen(name)+1];
strcpy(title,mr);
strcpy(owner,name);
balance=f;
}
void changetitle(char* newname)
{
if(strlen(newname)>strlen(title))
{
char* tmp=title;
title=new char[strlen(newname)+1];
strcpy(title,newname);
delete []tmp;
}
else
{
strcpy(title,newname); }
}
void changename(char* newname)
{
strcpy(owner,newname);
}
~Account()
{
delete []title;
title=NULL; }
private:
char* title;
char owner[MAX_CHAR];
float balance; friend ostream& operator<<(ostream & os,Account & b);
public:
Account& operator=(const Account& a)
{
if(this!=&a)
{
delete[] title;
title=new char[strlen(a.title)+1];
strcpy(title,a.title);
strcpy(owner,a.owner);
balance=a.balance; }
return *this;
} };
ostream& operator<<(ostream & os,Account & b)
{
os<<"who:"<<b.title<<" "<<b.owner<<" "<<b.balance<<endl;
return os;
}
int main()
{
Account acc("zhanger gou","Mr",1000);
Account ac1;
cout<<acc;
cout<<ac1;
ac1=acc;
cout<<ac1;
cout<<acc;
ac1.changename("er gou");
cout<<acc;
cout<<ac1;
ac1.changetitle("Re");
cout<<acc;
cout<<ac1; return 0;
}

[置顶] operator overloading(操作符重载,运算符重载)运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy)的更多相关文章

  1. [置顶] 运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy),三大件(bigthree problem)

    一般的我们喜欢这样对对象赋值: Person p1;Person p2=p1; classT object(another_object), or    A a(b); classT object = ...

  2. 运算符重载,浅拷贝(logical copy) ,vs, 深拷贝(physical copy),三大件(bigthree problem)

    一般的我们喜欢这样对对象赋值: Person p1;Person p2=p1; classT object(another_object), or    A a(b); classT object = ...

  3. C# to IL 5 Operator Overloading(操作符重载)

    Every operator overload that we use in C#, gets converted to a function call in IL. Theoverloaded &g ...

  4. [置顶] C++基础之六:运算符的重载

    网上太多有关运算符的重载了,但是写的太过的详细,不适合新手入门,特别是那什么++和--的前增量后增量重载,一元二元运算符重载,特殊运算符,下标运算符,new和delete,甚至是指针运算符的重载,吓退 ...

  5. C++ operator overload -- 操作符重载

    C++ operator overload -- 操作符重载 2011-12-13 14:18:29 分类: C/C++ 操作符重载有两种方式,一是以成员函数方式重载,另一种是全局函数. 先看例子 # ...

  6. C++ 操作符重载实践 & java没有重载操作符的思路

    实践如下: #include <iostream> using namespace std; class Book{ private: int page; public: Book(int ...

  7. C++ 运算符重载二(一元运算符重载)

    //一元运算符重载 #include<iostream> using namespace std; class Point { public: Point(int x,int y){ th ...

  8. C++重载流插入运算符和流提取运算符【转】

    C++的流插入运算符“<<”和流提取运算符“>>”是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream.cin和cout分别是 ...

  9. 20.C++- "&&","||"逻辑重载操作符的缺陷、","逗号重载操作符的分析

    "&&","||"逻辑重载操作符的缺陷 大家,都知道"&&","||"拥有"短 ...

随机推荐

  1. codeforces 401D (数位DP)

    思路:很明显的数位dp,设dp[i][j] 表示选取数字的状态为i,模m等于j的数的个数,那么最后的答案就是dp[(1<<n)-1][0].状态转移方程就是,dp[i|(1<< ...

  2. fedora下的dropbox

  3. suds 在python3.x上的安装并访问webservice

    类库安装 直接使用命令行:pip install suds 报错:Traceback (most recent call last):    File "setup.py", li ...

  4. adb logcat调试中常用的命令介绍

    Android日志系统提供了记录和查看系统调试信息的功能.日志都是从各种软件和一些系统的缓冲区中记录下来的,缓冲区可以通过 logcat 命 令来查看和使用. adb logcat 命令格式 : ad ...

  5. 在Mac上通过Sublime、Skim编辑LaTeX

    转自:http://painterlin.com/2014/08/10/Using-LaTeX-with-Sublime-and-Skim-for-Mac.html Sublime Text是一款非常 ...

  6. 【Hadoop代码笔记】通过JobClient对Jobtracker的调用详细了解Hadoop RPC

    Hadoop的各个服务间,客户端和服务间的交互采用RPC方式.关于这种机制介绍的资源很多,也不难理解,这里不做背景介绍.只是尝试从Jobclient向JobTracker提交作业这个最简单的客户端服务 ...

  7. 让浏览器进行跨域访问, 开发阶段需要跨域访问的测试方案 chrome的快捷方式里面 加 "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --args --disable-web-security

    Chrome浏览器 的快捷方式里加一个 命令可以使浏览器进行跨域访问 "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe ...

  8. homework-02 一坑到底的最大和联通图

    你在这个作业中学到了什么?  有什么好的设计值得分享?  感想如何 (太容易 / 太难 / 太无趣)? 我觉得这套题目有点偏难,我不像大牛那样,有很多算法可以选择,我是0算法基础的,所以遇到这题我一个 ...

  9. mlock家族:锁定物理内存

    Start Page Index History Last Change mlock家族:锁定物理内存 系统调用 mlock 家族允许程序在物理内存上锁住它的部分或全部地址空间.这将阻止Linux 将 ...

  10. Shell 脚本学习资料搜集

    Shell文档 ChinaUnix上大神“網中人”总结的Shell十三问,强烈推荐,这本书讲得比较精炼,而且都是一些Shell学习中容易把握不住的一些细节难点.每一问都写得非常精彩.ChinaUnix ...