c++重载

目录

重载,重写(复写,覆盖),隐藏

运算符重载


重载,重写(复写,覆盖),隐藏

1.重载(函数重载)
           必须在同一个类中,或者同一个源文件的普通函数之间(要求在同一个作用域中)
           例子一:
                       class  Cat   //同一个类中的eat叫做重载,不同类中的eat不叫重载
                       {
                            public:
                                       void eat()
                                       {

                                       }
                                       void eat(string food)
                                       {

                                       }
                       }
                      class Bscat:public Cat
                      {
                             public:
                                       void eat()
                                       {

                                       }
                                       void eat(string food,string otherfood,int n)
                                       {

                                       }

                      }
            例子二:
                     int add(int a,int b);
                     doble add(double a,double b);

   2.重写(复写,覆盖)--》发生在父子之间,多态
           子类重写了父类的同名虚函数
           要求一:父类的同名函数必须是虚函数
           要求二:子类必须重写父类同名虚函数(返回值类型,形参类型个数都要一模一样)

   3.隐藏--》发生在父子之间
             情况一: 子类写了跟父类同名的函数,但是子类同名函数的返回值或者参数类型个数跟父类的不相同
             情况二:子类写了跟父类一模一样的函数,但是父类的函数不是虚函数

运算符重载

1.概念
             C++提供了一种机制:允许程序员扩展基本运算符号的功能(让基本运算符的作用范围更广)
             比如:正常情况下,加法运算只能用于整数,小数,字符
                       如果现在有两个猫的对象c1,c2    c1+c2

   2.语法规则(运算符重载本质上就是个函数)
              返回值  operator运算符号(形参)
              {
                          运算符重载的代码;

              }
      运算符重载函数的调用有两种写法
                    写法一:按照人类的思维习惯去调用
                                      比如:加法      c1+c2
                                                大于号   c1>c2
                    写法二:按照函数调用的写法去调用
                                      c1.operator+(c2);
                                      c1.operator>(c2);

   3.运算符重载有两种表现形式
                   第一种:运算符重载作为类的成员函数
                                         默认可以使用this指针,参数就可以减少一个
                   第二种:运算符重载作为类的友元函数(不是成员函数)
                                         没有this指针,所有的参数都要写上
      总结:第二种写法是万能的,第一种不是万能的

   4.运算符重载的特点
                第一个:运算符重载,函数名很奇葩,统一叫做operator运算符
                第二个:运算符重载不能发明新的运算符号,只能重载已经存在的基本运算符号
                                operator@  --》不正确
                第三个:运算符重载最好不要改变运算符原本的语义
                                比如: 加法运算--》心目中默认的含义是把两个东西相加,合并
                第四个:如下运算符不能重载
                                ?:     ::     .   sizeof  

   

   5.重新认识string和cout以及cin
         (1)认识string中的运算符重载
             string str3=str1+str2;  重载加法
             str1=str2;  //重载了赋值
             str1[0];  //重载了中括号

        (2)认识ostream中的运算符重载
              第一点:输出单个变量   cout<<a;  //等价于函数调用  cout.operator<<(a);
              第二点:输出多个变量   cout<<a<<b<<c; //从左到右,一个个输出(每次调用运算符重载的函数,返回值都是ostream对象)
             底层原理:
                   class  ostream
                   {
                      public:
                                     ostream &operator<<(形参)
                                     {
                                             输出传递过来的实参;
                                             return *this;   
                                    }

                 }
                 ostream cout;
                 cout.operator<<(实参);  //输出单个变量
                 cout.operator<<(实参1).operator<<(实参2);  //输出多个变量

         (3)认识istream中的运算符重载
              第一点:输入单个变量   cin>>a;  //等价于函数调用  cin.operator>>(a);
              第二点:输入多个变量   cin>>a>>b>>c; //从左到右,一个个输入(每次调用运算符重载的函数,返回值都是istream对象)
             底层原理:
                   class  istream
                   {
                      public:
                                     istream &operator>>(形参)
                                     {
                                             获取键盘输入的内容存放到传递过来的实参中
                                             return *this;   
                                    }

                 }
                 istream cin;
                 cin.operator>>(实参);  //输入单个变量
                 cin.operator>>(实参1).operator>>(实参2);  //输入多个变量

   6.几个特殊的运算符重载
              (1)自增自减的重载
                        后置++和++前置
                 要求一:重载后置的++
                 Cat c1(5);
                 Cat c2=c1++;
                          返回值 operator++(int arg)     //参数int为了跟前置++区分                 
                          {

                          }
                要求二:重载前置的++
                 Cat c1(5);
                 Cat c2=++c1;
                          返回值 operator++()
                          {

                          }

              (2)重载输入和输出

#include <iostream>
using namespace std;

class Rect
{
public:
	Rect(int _w,int _h)
	{
		w=_w;
		h=_h;
	}
	void show()
	{
		cout<<"w is: "<<w<<"  h is: "<<h<<endl;
	}
	//把运算符重载声明成矩形类的友元函数
	friend Rect operator*(int n,Rect &rect);
private:
	int w;
	int h;
};

//注意:operator*跟矩形类没有任何关系,就是个普普通通的函数
Rect operator*(int n,Rect &rect)
{
	cout<<"重载乘法调用了"<<endl;
	rect.w=rect.w*n;
	rect.h=rect.h*n;
	return rect;
}

int main()
{
	//定义矩形对象
	Rect r1(5,7);
	/*
		条件反射:把人类思维习惯写的表达式--》转换成函数调用--》可以帮助分析清楚函数该怎么写
		3*r1--》3.operator*(r1)//你是来搞笑的,行不通(3不是一个对象)
		正确思路:把运算符重载成Rect类的友元函数
		3*r1--》operator*(3,r1)
	*/
	Rect r2=3*r1;
	r1.show();
	r2.show();
	
}

 上图是运算符重载作为类的友元函数。

#include <iostream>
using namespace std;

class Cat
{
public:
	Cat(int _age)
	{
		age=_age;
	}
	void show()
	{
		cout<<"age is: "<<age<<endl;
	}
	//重载加法运算,让两只猫可以做加法运算
	int operator+(Cat &other)
	{
		cout<<"加法重载被调用了,调用这个函数的对象地址是: "<<this<<endl;
		return age+other.age;
	}
private:
	int age;
};

int main()
{
	Cat c1(5);
	Cat c2(7);
	/*
		双目运算符
		分析运算符重载是如何调用的
		c1+c2-->c1.operator+(c2)
		c2+c1-->c2.operator+(c1)
	*/
	cout<<"主函数中c1地址: "<<&c1<<endl;
	cout<<"主函数中c2地址: "<<&c2<<endl;
	//cout<<"c1+c2 is:"<<c1+c2<<endl;
	cout<<"c1+c2 is:"<<c2+c1<<endl;
}

 上图是运算符重载实现两只猫的加法。

补充知识点C语言返回值和返回指针的区别

#include<stdio.h>

//返回的是值
int add(int a,int b)
{
	int temp;  //临时变量--》栈空间
	temp=a+b;
	return temp; //先备份值,然后自动释放
}

//返回的是地址(指针)
char *fun()
{
	char buf[10]="hello";  //临时变量--》栈空间
	printf("buf的首地址是: %p\n",buf);
	return buf; //自动释放
}
int main()
{
	// int m=77;
	// int n=99;
	// int ret=add(m,n); //返回的临时变量temp在释放之前,会在内存中备份一份值的副本
	// printf("m+n is: %d\n",ret);
	
	
	char *p=fun();
	printf("p指向的地址是: %p\n",p);
	printf("p里面存放的内容是: %s\n",p);
}

 由结果可以得知两者的区别。

#include <iostream>
using namespace std;

class Cat
{
public:
	Cat()
	{
		
	}
	Cat(int _age)
	{
		age=_age;
	}
	void show()
	{
		cout<<"age is: "<<age<<endl;
	}
	//重载后置的++
	Cat operator++(int arg)  //之所以后置的++必须要加上这个int参数,原因是为了跟前置的++区分
	{
		cout<<"重载了后置的++"<<endl;
		//定义一个临时对象
		Cat temp=*this;
		age=age+1;
		return temp;
	}
	
	//重载前置的++
	Cat operator++()
	{
		cout<<"重载了前置的++"<<endl;
		age=age+1;
		return *this;
	}

private:
	int age;
};



int main()
{
	Cat c1(5);
	//Cat c2=c1++;  //单目运算符
	//函数调用
	Cat c2=c1.operator++(666);
	c1.show();
	c2.show();
	
	Cat c3(8);
	//Cat c4=++c3;
	//函数调用 
	Cat c4=c3.operator++();
	c3.show();
	c4.show();

}

 

 由上图得知重载前置与后置的区别。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hqb_newfarmer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值