C++ 重载(函数和运算符)
如果我们创建两个或多个具有相同名称但参数数量或类型不同的成员,这就是 C++ 的重载。在 C++ 中,我们可以进行以下重载:
- 方法,
- 构造函数,和
- 索引属性
这是因为这些成员只有参数有所不同。
C++ 中的重载类型有
- 函数重载
- 运算符重载
C++函数重载
函数重载在C++中是指具有相同名称但参数不同的两个或多个函数的过程。在函数重载中,可以使用不同类型的参数或不同数量的参数来重新定义函数。通过这些差异,编译器才能区分这些函数。
函数重载的 优势 是可以增加程序的可读性,因为你不需要为相同的操作使用不同的名称。
C++函数重载示例
让我们看一个简单的函数重载示例,其中我们改变了add()方法的参数数量。
// 当参数数量不同时,进行函数重载的程序。
#include <iostream>
using namespace std;
class Cal {
public:
static int add(int a,int b){
return a + b;
}
static int add(int a, int b, int c)
{
return a + b + c;
}
};
int main(void) {
Cal C; // class object declaration.
cout<<C.add(10, 20)<<endl;
cout<<C.add(12, 20, 23);
return 0;
}
输出:
30
55
让我们来看一个简单的例子,当参数的类型不同时。
// 使用不同类型的参数进行函数重载的程序。
#include<iostream>
using namespace std;
int mul(int,int);
float mul(float,int);
int mul(int a,int b)
{
return a*b;
}
float mul(double x, int y)
{
return x*y;
}
int main()
{
int r1 = mul(6,7);
float r2 = mul(0.2,3);
std::cout << "r1 is : " <<r1<< std::endl;
std::cout <<"r2 is : " <<r2<< std::endl;
return 0;
}
输出:
r1 is : 42
r2 is : 0.6
函数重载与歧义
当编译器无法决定在重载函数中调用哪个函数时,这种情况被称为 函数重载 。
当编译器显示歧义错误时,编译器不会执行程序。
函数重载的原因:
- 类型转换。
- 带有默认参数的函数。
- 引用传参的函数。
- 类型转换:
让我们看一个简单的例子。
#include<iostream>
using namespace std;
void fun(int);
void fun(float);
void fun(int i)
{
std::cout << "Value of i is : " <<i<< std::endl;
}
void fun(float j)
{
std::cout << "Value of j is : " <<j<< std::endl;
}
int main()
{
fun(12);
fun(1.2);
return 0;
}
上面的例子显示了一个错误 ” fun(double)” 的调用是不明确的 。fun(10)将调用第一个函数。fun(1.2)根据我们的预测调用第二个函数。但是,在C++中,所有的浮点常量都被视为double而不是float,这意味着它不对应任何函数。如果我们将float替换为double,程序就可以运行。因此,这是从float到double的类型转换。
- 带有默认参数的函数
让我们看一个简单的例子。
#include<iostream>
using namespace std;
void fun(int);
void fun(int,int);
void fun(int i)
{
std::cout << "Value of i is : " <<i<< std::endl;
}
void fun(int a,int b=9)
{
std::cout << "Value of a is : " <<a<< std::endl;
std::cout << "Value of b is : " <<b<< std::endl;
}
int main()
{
fun(12);
return 0;
}
以上示例显示了一个错误:“调用重载的‘fun(int)’存在二义性”。fun(int a, int b=9)的调用有两种方式:第一种是通过使用一个参数调用函数,即fun(12),另一种是通过使用两个参数调用函数,即fun(4,5)。fun(int i)函数使用一个参数调用。因此,编译器无法在fun(int i)和fun(int a,int b=9)之间进行选择。
- 通过引用传递的函数
让我们看一个简单的例子。
#include <iostream>
using namespace std;
void fun(int);
void fun(int &);
int main()
{
int a=10;
fun(a); // error, which f()?
return 0;
}
void fun(int x)
{
std::cout << "Value of x is : " <<x<< std::endl;
}
void fun(int &b)
{
std::cout << "Value of b is : " <<b<< std::endl;
}
上面的例子显示了一个错误 ” 调用重载的’fun(int &)’是不明确的“。第一个函数接受一个整数参数,第二个函数接受一个引用参数作为参数。在这种情况下,编译器不知道用户需要哪个函数,因为在fun(int)和fun(int&)之间没有语法上的区别。
C++运算符重载
运算符重载是一种编译时多态,其中运算符被重载以为用户定义的数据类型提供特殊的含义。运算符重载用于重载或重新定义C++中的大多数运算符。它用于对用户定义的数据类型执行操作。例如,C++提供了将应用于内置数据类型的变量相加的能力。
运算符重载的优点是可以对同一操作数执行不同的操作。
以下运算符不可重载:
- 作用域运算符(::)
- Sizeof
- 成员选择器(.)
- 成员指针选择器(*)
- 三目运算符(?:)
运算符重载的语法
return_type class_name : : operator op(argument_list)
{
// body of the function.
}
return type 是函数返回的值的类型。
class_name 是类的名称。
operator op 是重载的操作符函数,其中op是被重载的操作符,而operator是关键字。
操作符重载规则
- 只能重载现有的操作符,不能重载新的操作符。
- 重载的操作符至少包含一个自定义数据类型的操作数。
- 不能使用友元函数来重载某些操作符。但是,可以使用成员函数来重载这些操作符。
- 当通过成员函数重载一元操作符时,参数不需要显式指定,而通过友元函数重载时需要一个参数。
- 当通过成员函数重载二元操作符时,需要一个显式参数,而通过友元函数重载时需要两个显式参数。
C++操作符重载示例
让我们看看C++中操作符重载的简单示例。在此示例中,定义了 void operator++() 运算符函数(在 Test 类内部)。
// 重载一元操作符 ++ 的程序
#include <iostream>
using namespace std;
class Test
{
private:
int num;
public:
Test(): num(8){}
void operator ++() {
num = num+2;
}
void Print() {
cout<<"The Count is: "<<num;
}
};
int main()
{
Test tt;
++tt; // 调用函数 "void operator ++()"
tt.Print();
return 0;
}
输出:
The Count is: 10
让我们看看重载二元操作符的简单示例。
// 重载二元操作符的程序。
#include <iostream>
using namespace std;
class A
{
int x;
public:
A(){}
A(int i)
{
x=i;
}
void operator+(A);
void display();
};
void A :: operator+(A a)
{
int m = x+a.x;
cout<<"两个对象的相加结果是:"<<m;
}
int main()
{
A a1(5);
A a2(4);
a1+a2;
return 0;
}
输出:
两个对象的相加结果是:9