C++函数重载
重载声明是指一个与之前已经在该作用域内声明过的函数或方法具有相同名称的声明,但是它们的参数列表和定义(实现)不相同。
当您调用一个重载函数**时,编译器通过把您所使用的参数类型与定义中的参数类型进行比较,决定选用最合适的定义。
C++运算符重载
(只有自定义的数据类型才可以实现运算符重载)
几种方式(成员函数重载 友元函数重载 普通函数重载) 合理选择~
普通函数重载一般不用吧 如果想访问类私有数据用友元函数方便
可以重定义或重载大部分C++内置的运算符~
重载的运算符时带有特殊名称的函数,函数名由关键字operator和其后要重载的运算符符号构成。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
Box operator+(const Box&);
operator + 返回类型Box 参数列表const Box& ..
声明加法运算符用于把两个 Box 对象相加,返回最终的 Box 对象。
大多数的重载运算符可被定义为普通的非成员函数或者被定义为类成员函数。如果我们定义上面的函数为类的非成员函数,那么我们需要为每次操作传递两个参数:
Box operator+(const Box&, const Box&);
重载+二元运算符:(注意 ① ②区别)
①
#include <iostream>
using namespace std;
class Box
{
public:
double getVolume(void)
{
return length * breadth * height;
}
void setLength( double len )
{
length = len;
}
void setBreadth( double bre )
{
breadth = bre;
}
void setHeight( double hei )
{
height = hei;
}
// 重载 + 运算符,用于把两个 Box 对象相加
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
// 程序的主函数
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
Box Box3; // 声明 Box3,类型为 Box
double volume = 0.0; // 把体积存储在该变量中
// Box1 详述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// Box2 详述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// Box1 的体积
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
// Box2 的体积
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
// 把两个对象相加,得到 Box3
Box3 = Box1 + Box2;
// Box3 的体积
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume <<endl;
return 0;
}
②
#include <iostream>
using namespace std;
class Box
{
public:
double getVolume(void)
{
return length * breadth * height;
}
void setLength( double len )
{
length = len;
}
void setBreadth( double bre )
{
breadth = bre;
}
void setHeight( double hei )
{
height = hei;
}
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
// 重载 + 运算符,用于把两个 Box 对象相加
Box operator+(const Box& a,const Box& b)
{
Box box;
box.length = a.length + b.length;
box.breadth = a.breadth + b.breadth;
box.height = a.height + b.height;
return box;
}
// 程序的主函数
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
Box Box3; // 声明 Box3,类型为 Box
double volume = 0.0; // 把体积存储在该变量中
// Box1 详述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// Box2 详述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// Box1 的体积
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
// Box2 的体积
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
// 把两个对象相加,得到 Box3
Box3 = Box1 + Box2;
// Box3 的体积
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume <<endl;
return 0;
}
自己补充一个重载+二元运算符的例子
如果想要重载+让 一个对象与一个数字相加,并且不受顺序影响,一个小demo
#include <iostream>
using namespace std;
class Test
{
public:
Test();
Test(int n);
Test operator+(const Test& obj);
//对象+对象
Test operator+(const int b);
//对象+整形数据
friend Test operator+(const int b,Test obj);
void show();
private:
int a;
};
Test::Test()
{
a=0;
}
Test::Test(int n)
{
a=n;//构造函数
}
Test Test::operator+(const Test& obj)
{
return Test(this->a+obj.a);
}
Test Test::operator+(const int b)
{
return Test(a+b);
}
void Test::show()
{
cout<<a<<endl;
}
Test operator+(const int b,Test obj)
{
return obj+b;//友元函数
}
int main( )
{
Test t1(100);
int m=100;
Test t2;
t2=t1+m;
t2.show();
Test t3;
t3=m+t1;
//这时候会调用友元函数
t3.show();
return 0;
}
重载<< >>运算符
(<< >>主要适用于输出输入内置的数据类型)
(实现对象可以进行输出 所以觉得一般定义为友元函数合适)
(重载<< >>来操作自定义的数据类型)
运算符重载的函数需要返回一个ostream对象,其实cout时ostream的一个输出流对象。函数第一个参数ostream &out,在运行代码中,只能有一个cout对象,所以这里使用引用的方式,保证全局只有一个该对象
基本
ostream& operator<<(ostream& out, const ClassType& obj)
{
out << .. << .. <<...;
return out;
}
istream& operator<<(istream& in, ClassType& obj)
{
in >> .. >> .. >>...;
return in;
}
①(普通函数重载 << >>运算符)
#include <iostream>
#include<cstring>
using namespace std;
class Test
{
public:
Test(const char *nam,int ag):age(ag){strcpy(name,nam);}
char* Getname(){return name;}
int& Getage(){return age;}
//左值:代表一个在内存中占有确定位置的对象(换句话说就是有一个地址)
//右值:利用排他性定义即可
//必须加上引用符号 Getage返回age的引用
//https://blog.csdn.net/xuwqiang1994/article/details/79924310
private:
char name[5];
int age;
};
ostream& operator<<(ostream& out,Test& t1)
{
out<<t1.Getname()<<" "<<t1.Getage();
//内部实现输出~
return out;
}
istream& operator>>(istream &in,Test & t2)
{
char name[5]={0};
int age=0;
in>>name>>age;
//内部实现输入~
if(in)
{
strcpy(t2.Getname(),name);
//
t2.Getage()=age;
}
else{}
return in;
}
int main( )
{
Test t1("Mike",21);
cout<<t1<<endl;//输出
cin>>t1;//输入
cout<<t1<<endl;//输出
return 0;
}
②(使用友元函数重载<< >>)
#include "iostream"
#include "cmath"
#include"cstring"
using namespace std;
class Test
{
public:
Test(const char *nam,int ag):age(ag){strcpy(name,nam);}
friend ostream& operator<<(ostream &out,const Test &t1)
{
out<<t1.name<<" "<<t1.age;
return out;
}
friend istream&operator>>(istream &in,Test& t1)
{
char name[5]={0};
int ag=0;
in>>name>>ag;
if(in)
{
strcpy(t1.name,name);
t1.age=ag;
}
else{}
return in;
}
private:
char name[5];
int age;
};
int main()
{
Test t1("Mike",21);
cout<<t1<<endl;
cin>>t1;
cout<<t1<<endl;
return 0;
}
前置递增 后增递增运算符重载
(功能是先++再返回 先记录当前再++)
先计算,后赋值: 函数里面,先++,再返回。返回Test的引用,主要是为了H行执行一遍++Test后,再执行++(++Test),这里的++Test还是原来的Test对象,这样保证操作的是一个对象~
先赋值,再计算:传入int占位符即可。函数里面,先记录当前的值,再进行++,返回原先记录的值,返回不能是引用,因为如果是引用,相当于返回的是tmp的引用,而tmp是一个局部变量,在函数运行结束后就会释放,如果再去访问t1,发现结果没变~
#include<iostream>
using namespace std;
class Test {
friend ostream& operator<<(ostream& cout,Test t1);
public:
Test() {
num = 0;
}
//重载++i运算符
//说明这是一个前缀形式
Test & operator++() {
//先++ 再返回
num++;
return *this;
}
//重载i++运算符
//int在括号里面是为了向编译器说明这是一个后缀形式
Test operator++(int) {
//先记录 再返回
Test tmp = *this;
//后递增
num++;
//再返回记录的结果
return tmp;
}
private:
int num;
};
ostream & operator<<(ostream &cout,Test t1) {
cout << "num=" << t1.num;
return cout;
}
int main() {
Test t1;
cout << t1++ << endl;
cout << t1 << endl;
Test t2;
cout << ++(++t2)<<endl;// H
cout << t2 << endl;
return 0;
}