C++之运算符重载

运算符重载

  1. 运算符重载的概念
  2. 运算符重载
  3. 用友元实现运算符重载

运算符重载的概念

什么是运算符重载

重载,重新载入,比如函数重载,对一个已有的函数赋予一个新的定义,因此一个名字就能代表不同的含义。
运算符也是可以重载的,比如在cout时,能接受不同类型的数据并输出,这个就是运算符的重载。
因此,运算符重载,指的是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

为什么要进行运算符重载

运算符重载,可以让运算符去适应不同的数据类型,对于基本数据类型,系统给出了运算符的操作规则,但对于自定义类型来说,系统是无法给出操作规则的。

//  如下:
Complex c3 = c2 + c1;
  1. Complex是用户自定义类类型(类或结构体)。
  2. 在这里两个自定义类型的变量,编译器根本不知道怎么去计算。
  3. 编译器提供了一种机制,让用户自己去完成,自定义类型的计算。
  4. 这个机制就是运算符重载。

运算符重载

运算符重载定义

关键字

operator,通过关键字修饰运算符来构成运算符重载

定义

函数返回值类型 operator运算符(参数列表)
{
函数体;
}
①返回值类型:这个运算符计算之后要返回一个什么值。
②operator运算符:表示运算符重载,也可以理解为一个函数名
③参数列表:这个运算符需要的操作数。
④函数体:这个运算符我们赋予他什么新的规则。

运算符重载特性

  1. 运算符重载,运算符重新定义新的操作规则。
  2. 几乎所有的运算符都可以被重载。 除以下:. :: ?: sizeof这些运算符之外。
  3. 运算符重载基本上出现在类中和结构中。
  4. 运算符重载要满足运算符原来的规则。
  5. 运算符理解为函数的一个表现。

常见运算符重载示例

class CMyCard
    {
	int val;
    public:
	int operator+(CMyCard const& mc)
	{
	    return this->val + mc.val;
	}
    }mc1,mc2;		//mc1,mc2为类对象
    int cardVal;	//整型变量    
    //直接调用的+号运算符,计算的是两个对象之和,把结果返回给到整型变量。
    cardVal = mc1 + mc2;
    //通过对象mc1点出成员运算符重载的函数,把mc2做为参数传递进去计算。也是把结果返回给整型变量。			
    cardVal = mc1.operator+(mc2);

分析:
示例中表现加号重载,重载让两个对象相加,加的是对象里面的私有成员val的
值,通过 int operator +(CMyCard const& mc) 这个函数体现出来。
在函数体内设定两个变量的相加,所以返回值可以是一个int类型的变量,也是
其他的,需要返回什么就可以返回一个什么。比如,可以返回一个CMyCard类型也是
常见操作。
基本大部分运算符重载都可参照该示例进行定义。

自增运算符重载示例

   class CMyCard
    {
	int val;
    public:
	CMyCard& operator ++()//++前置
	{
	    this->val++;
	    return *this;
	}
    };	
  <strong>  ++前置,先自增,再返回,返回自身类型,返回值类型使用引用。

自增运算符重载示例

    class CMyCard
    {
	int val;
    public:
	CMyCard operator ++(int)//++后置
	{
	    CMyCard temp = *this;
	    this->val++;
	    return temp;
	}
    };	

    ++后置,先返回,再自增,因此先用临时变量备份自身原来的数据,自身数据改变。返回临时对象。因为是临时对象,返回值类型不能使用引用。

运算符重载注意事项

  1. 运算符重载,是重新定义运算符的操作类型,该运算符原来能操作的类型是系统预先设置好的,通过运算符重载,可以加载用户需要操作的类型。
  2. 对于运算符重载的调用,可以直接使用运算符,也可以显示调用(通过类对象点出运算符)。
    注意:显示调用需要该运算符操作属于该类。
  3. 考虑参数列表,运算符需要和操作数一起组成表达式,参数列表就是用来表示操作数。
    注意:运算符重载在类中,那么this指针所指的调用者对象也属于其中一个操作数。
  4. 、考虑函数返回值,不同的运算符会有不同的返回,要满足运算符本来的规则。

用友元实现运算符重载

类已经实现且无法修改的情况下,需要进行运算符重载,就可以通过友元的方式来进行实现。

输入输出的运算符重载

    class CMyCard
    {
	int val;
    public:
	friend istream >> (istream & is, CMyCard& mc);//输入
	friend ostream << (ostream & os, CMyCard& mc);//输出    
    };	

输入输出的运算符重载

    //在类外定义
    istream& >> (istream & is, CMyCard& mc)
    {
	is >> mc.val;
	return is;
    }

    ostream& << (ostream & os, CMyCard& mc)
    {
	os << mc.val;
	return os;
    }

练习代码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
class Person
{
private:
    int id;
    string name;
public:
    Person operator +(const Person  &p)
    {
        this->id += p.id;
        this->name = this->name + p.name;
        return *this;
    }
    Person &operator ++()
    {
        this->id += 1;
        return *this;
    }
    Person operator ++(int)
    {
        Person p1 = *this;
        this->id += 1;
        return p1;
    }
    Person(int id, string name)
    {
        this->id = id;
        this->name = name;
    }
    void get()
    {
        cout << "id:" << id << endl << "name:" << name << endl;
    }
    int Get()
    {
        return id;
    }
    ~Person()
    {
    }
    friend ostream& operator << (ostream& os, Person& p);
};

ostream& operator << (ostream& os,Person&p)
{
    os << p.id;
    return os;
}

class A
{
    int id;
public:
    A(int id)
    {
        this->id = id;
    }
};
class smartpoint
{
    Person* ps;
public:
    smartpoint(Person* ps)
    {
        this->ps = ps;
    }
    Person* operator->()
    {
        return this->ps;
    }
    Person& operator*()
    {
        return *this->ps;
    }
    void fun()
    {
        cout << "fun函数" << endl;
    }
    ~smartpoint()
    {
        if (ps != NULL)
        {
            delete ps;
            ps = NULL;
        }
        cout << "智能指针释放了" << endl;
    }
};
int main()
{
    Person p(1, "Ye");
    Person p1(2, "Sir");
    p =p+ p1;
    p.get();
    p++;
    p.get();
    ++p;
    p.get();
    cout << p << endl;
    cout << endl;
    {
        smartpoint sp(new Person(1,"Yesir"));
        sp->get();
        sp.fun();
    }
    system("pause");
    return 0;
}

智能指针

智能指针是一种托管资源空间的技术,可以访问空间、模拟原生指针的行为,只是在原生指针生命周期结束时,释放资源。

class smartpoint
{
    Person* ps;
public:
    smartpoint(Person* ps)
    {
        this->ps = ps;
    }
    Person* operator->()
    {
        return this->ps;
    }
    Person& operator*()
    {
        return *this->ps;
    }
    void fun()
    {
        cout << "fun函数" << endl;
    }
    ~smartpoint()
    {
        if (ps != NULL)
        {
            delete ps;
            ps = NULL;
        }
        cout << "智能指针释放了" << endl;
    }
};

int main()
{
	    cout << endl;
	 //智能指针死亡, 调用析构, 在析构里释放Person申请的内存, 避免了内存泄漏的问题
    {
        smartpoint sp(new Person(1,"Yesir"));
        sp->get();
        sp.fun();
    }
}

使用运算符重载实现string类的功能

//利用运算符重载实现string类的功能
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
using namespace std;
class String
{
    char* str;
public:
    String(const char* str)
    {
        this->str = new char[strlen(str) + 1];
        strcpy(this->str, str);
    }
    void GetStr()
    {
        cout << str <<endl;
    }
    //获取长度
    int lengt()
    {
        return strlen(str);
    }
    //拷贝
    String(const String& s)
    {
        str = new char[strlen(s.str) + 1];
        strcpy(str, s.str);
    }
    //拷贝两个
    String(const String& s, const String& s1)
    {
        this->str = new char[strlen(s.str) + strlen(s1.str) + 1];
        this->str = strcat(s.str, s1.str);
    }
    //拼接
    char* operator+(String& s)
    {
        int len = strlen(this->str) + strlen(s.str);
        char* data = new char[len+1];
        data = strcat(this->str, s.str);
        return data;
    }
    bool operator<(String& s)
    {
        return strlen(this->str) < strlen(s.str);
    }
    bool operator>(String& s)
    {
        return strlen(this->str) > strlen(s.str);
    }
    bool operator==(String& s)
    {
        return strlen(this->str) == strlen(s.str);
    }
};
using namespace std;
int main()
{
    String str("Yesir");
    String str1("abcde");
    String s = str + str1;
    s.GetStr();
    cout << (str < str1) << endl;
    cout << (str > str1) << endl;
    cout << (str == str1) << endl;
    //cout << str + str1 << endl;
    //string s2 = "Yesir";
    //string s1 = "abc";
    system("pause");
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值