• C++——运算符重载(上)


    运算符重载

    运算符重载概念:对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

    e.g:

    对于内置数据类型,编译器知道如何进行运算

    int a = 10;
    int b = 10;
    int c = a + b;
    

    对于一些自定义的数据类型,编译器不知道该如何进行运算,所有需要我们进行运算符重载

    class Person
    {
    public:
        int m_A;
        int m_B;
    }
    
    Person p1;
    p1.m_A = 10;
    p1.m_B = 10;
    
    Person p2;
    p2.m_A = 10;
    p2.m_B = 10;
    
    //编译器不知道该如何进行运算,所以需要我们自己进行运算符重载
    Person p3 = p1 + p2;
    

    通过自己写的成员函数,可以实现两个对象相加属性后返回新的对象

    Person PersonAddPerson(Person &p)
    {
        Person temp;
        temp.m_A = this->m_A + p.m_A;
        temp.m_B = this->m_B + p.m_B;
        return temp;
    }
    

    对于编译器所给的加法运算通用名称进行重载

    1.通过成员函数重载+符号

    Person operator+ (Person &p)
    {
        Person temp;
        temp.m_A = this->m_A + p.m_A;
        temp.m_B = this->m_B + p.m_B;
        return temp;
    }
    
    Person p3 = p1.operator+(p2);//实际操作
    //简化为
    Person p3 = p1 + p2;
    

    2.通过全局函数重载+符号

    Person operator+ (Person &p1,Person &p2)
    {
        Person temp;
        temp.m_A = p1.m_A + p2.m_A;
        temp.m_B = p1.m_B + p2.m_B;
        return temp;
    }
    
    Person p3 = operator+(p1,p2);//实际操作
    //简化为
    Person p3 = p1 + p2;
    

    1 加号运算符重载

    作用:实现两个自定义数据类型相加的运算

    #include <iostream>
    using namespace std;
    
    //加号运算符重载
    
    class Person
    {
    //public:
    //	//1.通过成员函数对加法运算符进行重载
    //	Person operator+(Person &p)
    //	{
    //		Person temp;
    //		temp.m_A = this->m_A + p.m_A;
    //		temp.m_B = this->m_B + p.m_B;
    //		return temp;
    //	}
    
    public:
    
    	int m_A;
    	int m_B;
    };
    //2.通过全局函数对加法运算符进行重载
    Person operator+(Person &p1, Person &p2)
    {
    	Person temp;
    	temp.m_A = p1.m_A + p2.m_A;
    	temp.m_B = p1.m_B + p2.m_B;
    	return temp;
    }
    //运算符重载也可以发生函数重载
    Person operator+(Person &p1, int val)
    {
    	Person temp;
    	temp.m_A = p1.m_A + val;
    	temp.m_B = p1.m_B + val;
    	return temp;
    }
    
    void test01()
    {
    	Person p1;
    	p1.m_A = 10;
    	p1.m_B = 10;
    	Person p2;
    	p2.m_A = 20;
    	p2.m_B = 20;
    
    	Person p3 = p1 + p2;
    	//成员函数重载的本质调用
    	//Person p3=p1.operator+(p2);
    	//全局函数重载的本质调用
    	//Person p3 = operator+(p1, p2);
    
    	cout << "p3.m_A = " << p3.m_A << endl;
    	cout << "p3.m_B = " << p3.m_B << endl;
    
    	//调用重载的函数
    	Person p4 = p1 + 10;//Person + int
    	cout << "p4.m_A = " << p4.m_A << endl;
    	cout << "p4.m_B = " << p4.m_B << endl;
    
    }
    
    
    int main()
    {
    	test01();
    
    	system("pause");
    
    	return 0;
    }
    

    总结1:对于内置的数据类型的表达式的的运算符是不可能改变的

    总结2:不要滥用运算符重载

    2 左移运算符重载

    作用:可以输出自定义数据类型

    class Person {
    	friend ostream& operator<<(ostream& out, Person& p);
    
    public:
    
    	Person(int a, int b)
    	{
    		this->m_A = a;
    		this->m_B = b;
    	}
    
    	//成员函数 实现不了  p << cout 不是我们想要的效果
    	//void operator<<(Person& p){
    	//}
    
    private:
    	int m_A;
    	int m_B;
    };
    
    //全局函数实现左移重载
    //ostream对象只能有一个
    ostream& operator<<(ostream& out, Person& p) {
    	out << "a:" << p.m_A << " b:" << p.m_B;
    	return out;
    }
    
    void test() {
    
    	Person p1(10, 20);
    
    	cout << p1 << "hello world" << endl; //链式编程
    }
    
    int main() {
    
    	test();
    
    	system("pause");
    
    	return 0;
    }
    

    总结:重载左移运算符配合友元可以实现输出自定义数据类型

    3 递增运算符重载

    作用: 通过重载递增运算符,实现自己的整型数据

    #include <iostream>
    using namespace std;
    
    //重载递增运算符
    class MyInteger
    {
    	//友元声明
    	friend ostream & operator<<(ostream &cout, MyInteger &Myint);
        
    public:
    	MyInteger()
    	{
    		m_Num = 0;
    	}
    	//重载前置++运算符,返回引用类型是为了一直对一个数据进行递增
    	MyInteger & operator++()
    	{
    		//先进行++操作
    		m_Num++;
    		//返回自身
    		return *this;
    	}
    	//重载后置++运算符,
    	//void operator++(int)  int 是一个占位参数,可以用来区分前置和后置
    	//后置递增必须要返回值,不能返回引用,如果返回引用就等于返回一个局部变量的引用
    	MyInteger operator++(int)
    	{
    		//先记录当前的数据
    		MyInteger temp = *this;
    
    		//再进行++操作
    		this->m_Num++;
    
    		//再返回记录的数据值
    		return temp;
    	}
        
    private:
    	int m_Num;
     };
    
    //重载左移运算符
    ostream & operator<<(ostream &cout, MyInteger &Myint)
    {
    	cout << Myint.m_Num;
    	return cout;
    }
    //对前置递增运算符进行测试
    void test01()
    {
    	MyInteger Myint;
    	//cout << Myint << endl;
    	cout << ++(++Myint) << endl;
    	cout << Myint << endl;
    }
    
    //对后置递增运算符进行测试
    void test02()
    {
    	MyInteger myint;
    
    	cout << myint++ << endl;
    
    	cout << myint << endl;
    
    }
    int main()
    {
    	test01();
    
    	test02();
    
    	system("pause");
    
    	return 0;
    }
    

    总结: 前置递增返回引用,后置递增返回值

    自己练习递减运算符的重载

    #include <iostream>
    using namespace std;
    
    //递减运算符重载
    class MyInteger
    {
    	friend ostream & operator<<(ostream & cout, MyInteger myint);
    
    public:
    	MyInteger()
    	{
    		this->m_Num = 10;
    	}
    	
    	//重载前置左移运算符
    	MyInteger & operator--()
    	{
    		//先进行--操作
    		this->m_Num--;
    		//返回对象本身
    		return *this;
    	}
    
    	//重载后置左移运算符
    	MyInteger operator--(int)
    	{
    		//先记录对象当前值
    		MyInteger temp = *this;
    		//进行--操作
    		this->m_Num--;
    		//再返回记录的值
    		return temp;
    	}
    
    private:
    	int m_Num;
    };
    //重载左移运算符
    ostream & operator<<(ostream & cout, MyInteger myint)
    {
    	cout << myint.m_Num;
    	return cout;
    }
    
    void test01()
    {
    	MyInteger myint;
    	cout << myint << endl;
    	cout << --myint << endl;
    	cout << myint << endl;
    }
    
    void test02()
    {
    	MyInteger myint;
    	cout << myint << endl;
    	cout << myint-- << endl;
    	cout << myint << endl;
    }
    
    int main()
    {
    	//test01();
    
    	test02();
    
    	system("pause");
    
    	return 0;
    }
    
    吾生也有涯,而知也无涯
  • 相关阅读:
    学习网页栅格系统的几篇好文
    [转载]iis6配置使用页面Gzip压缩提速
    img标签的src=""会引起的Page_Load多次执行
    基于sliverlight + wcf的web 文字版IM 示例
    Enterprise Library 4.1学习笔记8缓存应用程序块之FileDependency
    windows 2008上启用防火墙后sqlserver 2005经常出现连接超时的解决办法
    负载均衡环境下的web服务器处理
    Ado.Net连接池的速度测试
    [转载]网页栅格系统研究(1):960的秘密
    css基础:把所有背景图都集成在一张图片上,减少图片服务器请求次数
  • 原文地址:https://www.cnblogs.com/daimasanjiaomao/p/13788517.html
Copyright © 2020-2023  润新知