c++基础知识点(4)运算符重载.特殊运算符重载.友元运算符重载

先上总结:

tips

​​​​​​​

        1. () 【】只能采用成员函数形式重载

        2.流重载采用友元方式

        3. 这五种运算符不能重载

        (1). 成员访问运算符

        (2)* 成员指针访问运算符

        (3)::域运算符

        (4)sizeof 长度运算符

        (5)? : 条件运算符

        单目运算符

        a++ ++a a-- --a等

        双目运算符

        a=b+c等

        三目运算符

        a?b:c;

三目运算符口诀:真前假后 

一.运算符重载

1.什么是运算符重载?

赋予运算符具有操作自定义数据类型的功能。

2.运算符重载的实质是什么?

本身实质其实就是函数调用。

3.运算符重载函数的写法

函数返回值  函数名(函数参数)

(1)返回值类型:运算完成后的值决定的

(2)函数名:operator加上运算符组成函数名 例如 operator+

(3)参数: 看运算符的操作数,具体参数个数看你重载函数形式是什么。

(4)函数体:具体看你的做的事情,写运算符具体想要的操作

二.友元函数运算符重载

关键字: friend 函数返回值 函数名(函数参数)

例子:

#include<iostream>
using namespace std;
class data
{
    public:
        data(int a,int b):a(a),b(b){}
        void printf()
        {
             cout<<a<<endl;
             cout<<b<<endl;
        }
    friend data operator+(data one,data two);、
    bool opera>(data obj)
    {
        if(this->a > obj.a)
        {
            return ture;
        }
        else
        {
            return false;
        }
    }
    private:
        int a;
        int b;
};
//友元重载:参数个数就是操作数
data operator+(one.a+two.a,one.b+two.b)
{
    return data(one.a+two.a,one.b+two.b);
}
int main()
{
    data one(1,1);
    data two(2,0);
    data three;
    three=one+two;  //隐式调用
    /*
    //显示调用
    data result;
    result=operator+(one,two);
    */
    /*
    if(one>two) //one>two 是布尔类型
    {
        cout<<"one 比较大"<<endl;
    }
    */
    //对象可以表示一个数据,所以参数应该少一个
    if(one.operator>(two))
    {
        cout<<"one比较大"<<endl;
    }
    return 0;
}

三.特殊运算符重载

流运算符

1.>>

2.<<

流运算符重载

cin类型 istream类的对象

#include<iostream>
using namespace std;
/************************************************************************
* 文件说明
************************************************************************/
class Demo{
	public:
		Demo(int x) : x(x){}
		friend istream & operator>>(istream &in, Demo &obj){
			in >> obj.x;
			return in;
		}
#if 0
		int operator+(Demo &obj){
			return x+obj.x;
		}
#else
		friend int operator+(Demo &obj1, Demo &obj2){
			return obj1.x + obj2.x;
		}
#endif
	private:
		int x;
};
int main(int argc, char *argv[])
{
	Demo a(15), b(1);

	cin >> a >> b; // 将标准输入流数据,先赋值给 a,然后将标准输入流剩下的数据,赋值给b

	cout << a + b << endl;  // cout << operator+(a, b) << endl;
    return 0;
}
/******************************end of file******************************/

cout类型 ostream类的对象

#include<iostream>
using namespace std;
/************************************************************************
* 文件说明
************************************************************************/
class Demo{
	public:
		Demo(int x) : x(x){}
	/*
	 * 友元运算符重载函数:
	 *		friend 数据类型 operator(<形参列表>)
	 *		{
	 *			//函数体
	 *		}
	 *
	 *		注意:
	 *			1、friend友元 打破类的封装,因此 运算符重载函数的形参个数 = 运算符的操作数个数。
	 *			2、当运算符的 第一操作数 为基本类型或者标准类型,就必须使用友元
	 * */
	friend ostream & operator<<(ostream &out, Demo &obj);
	friend int operator+(int x, Demo &obj){
		return x + obj.x;
	}
#if 0
	friend int operator+(Demo &obj, int x){
		return obj.x+x;
	}
#else
	int operator+(int x){
		return this->x + x;
	}
#endif
	private:
		int x;
};
ostream & operator<<(ostream &out, Demo &obj)
{
	// 将 obj.x 这个数值 插入到标准数据流中
	out << obj.x;
	return out;
}
int main(int argc, char *argv[])
{
	Demo a(13);
	cout << a << endl;		//运算符重载函数,只能是友元
	cout << 1 + a << endl;	//运算符重载函数,只能是友元
	cout << a + 1 << endl;  //运算符重载函数,既可以使用友元,又可以使用成员
	/*
	 * cout 标准输出流对象,类型是 ostream &,相当于是给标准输出流 取的 别名为 cout
	 * */ 
    return 0;
}
/******************************end of file******************************/

a++

++a

#include<iostream>
using namespace std;
/************************************************************************
* 文件说明
************************************************************************/
class Demo{
	public:
		Demo(int x):x(x){}
#if 0
		int operator++(){ // 前++
			return ++this->x;
		}
		int operator++(int){ //后++,此处int没有任何作用,只是一个占位符,用来区分 前++
			return x++;
		}
#else					// a++ ==> a = a + 1;	
		friend int operator++(Demo &obj){ // 前++
			return ++obj.x;
		}
		friend int operator++(Demo &obj, int){ //后++,此处int没有任何作用,只是一个占位符,用来区分 前++
			return obj.x++;
		}
        /*friend demo operator++(demo &obj,int)
          {
               demo tmp(obj.x);
                obj.x++;
                return tmp;         //返回局部对象
          }
#endif
		friend ostream &operator<<(ostream &out, Demo &obj){
			out << obj.x;
			return out;
		}
	private:
		int x;
};
int main(int argc, char *argv[])
{
	Demo a(12);
	cout << ++a << endl;	//cout << a.operator++() << endl;
	cout << a++ << endl;    //cout << a.operator++(int) << endl;
	cout << a << endl;
    return 0;


}

tips:

1.返回局部对象,其实是将局部对象的内容拷贝出去

2.当局部对象空间被销毁,其返回的数值 暂存常量区

3.该函数外部可以定义同类型的对象保存,也可使用 const 修饰的引用类型 取别名

【】

1、重载[] 运算符实现:
     *            Demo obj(6);
     *            for(int i = 0; i < 6; i++){
     *                cin >> obj[i];
     *            }
     *            for(int i = 0; i < 6; i++){
     *                cout << obj[i] << " ";
     *            }
     *            cout << endl;

#include <iostream>
using namespace std;
class demo
{
    public:
        demo(int a=0)
        {
            p=new int[a+1];
        }
        ~demo()
        {
            delete []p;
        }
        int &operator[](int i);
    private:
        int * p;
        int a;
};
int &demo::operator[](int i)
{
    return this->p[i];
}
int main()
{
    demo A(6);
    for(int i=0;i<6;i++)
    {
        cin>>A[i];
    }
    for(int i=0;i<6;i++)
    {
        cout<<A[i]<<" ";
    }
    cout<<endl;
    return 0;
}

tips:1.函数的数据类型,一般看 返回值的类型。

         2.如果函数返回的是类的成员,期待在函数外部能够修改,使用该成员的内容,那么函数数据类型必须是引用类型。

()

2、重载() 运算符实现:
     *            Demo obj(1, 1);
     *            cout << obj() << endl;  ==> 打印出 2
     *            cout << obj(2, 2) << endl; ==> 打印出 4

#include <iostream>
using namespace std;
class demo
{
    public:
        demo(int m,int n):m(m),n(n){}
        int operator()()
        {
            return this->m+this->n;
        }
        int operator()(int m,int n)
        {
            return m+n;
        }
    private:
        int m,n;
};
int main()
{
    demo a(1,1);
    cout<<a()<<endl;
    cout<<a(2,2)<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/fuyuyf/article/details/125859762