重载函数:函数名相同,函数的参数个数或者参数的类型不同。(注:不能用函数的返回值区别重载函数)
在全局和类的范围内都可以定义重载函数
①全局范围内定义重载函数
代码Ⅰ:
#include "stdafx.h"
void PrintMessage(const char* Text,const char* Caption)
{
printf("Text = %s, Caption = %s\n", Text, Caption);
}
void PrintMessage(const char* Text, int Type)
{
printf("Text = %s, Type = %d\n", Text, Type);
}
int _tmain(int argc, _TCHAR* argv[])
{
PrintMessage("Hello C++","welcome");
PrintMessage("Hello C++", 1);
return 0;
}
②类范围内定义重载函数
代码Ⅱ:
#include "stdafx.h"
class Message
{
public:
Message(){};
void PrintMessage(const char* Text , const char* Caption);
void PrintMessage(const char* Text , int Type);
};
void Message::PrintMessage(const char* Text ,const char* Caption)
{
printf("Text = %s, Caption = %s\n", Text, Caption);
}
void Message::PrintMessage(const char* Text, int Type)
{
printf("Text = %s, Type = %d\n", Text, Type);
}
int _tmain(int argc, _TCHAR* argv[])
{
Message pMessage;
pMessage.PrintMessage("Hello C++","welcome");
pMessage.PrintMessage("Hello C++",1);
return 0;
}
编译器调用重载函数的规则:
①具有与实参类型相同的形参的重载函数(参考代码Ⅰ)
②转换实参,将T转换为T&(注:此处是引用,不是取地址)或T& 转化为T,或T转换为const T,然后寻找形参类型匹配的重载函数(T为某数据类型)
代码Ⅲ:
#include "stdafx.h"
void PrintMessage(const char* Text, const char* Caption)
{
printf("Message: Text = %s, Caption = %s\n", Text, Caption);
}
void PrintMessage(const char* Text,int& Type) // 引用的目的就是在函数中可以修改相应的值
{
printf("Message: Text = %s, Type = %d\n", Text, Type);
}
int _tmain(int argc, _TCHAR* argv[])
{
int i = 1;
PrintMessage("OK", i);
return 0;
}
③实参进行标准(隐式)类型转换,一般的转换顺序是char、short -> int -> unsigned -> double -> float ,然后寻找形参类型匹配的重载函数
代码Ⅳ:
#include "stdafx.h"
void PrintMessage(const char* Text, int Type)
{
printf("Message: Text = %s, Type = %d\n", Text, Type+1);
}
void PrintMessage(const char* Text,unsigned int Type)
{
printf("Message: Text = %s, Type = %d\n", Text, Type);
}
int _tmain(int argc, _TCHAR* argv[])
{
char i = 1;
PrintMessage("OK", i);
return 0;
}
此处运行的结果是2,而不是1,表明调用的是第一个重构函数。即char->int->unsigned int 的顺序
对于系统预定义的数据类型,我们可以采取显式类型转换和隐式类型转换两类,但是对于用户自定义的类类型,c++提供类型转换函数和转换构造函数进行转换。
④使用构造函数转换实参,使其与某一重载函数匹配,例如,如果类A有构造函数A(int),那么int型的实参可以被编译器转换为类A的临时对象(代码Ⅴ)
代码Ⅴ:
// 我们在此处定义一个复数类
#include "stdafx.h"
class Complex
{
private:
double real;
double imag;
public:
Complex(double real, double imag)
{
this->real = real;
this->imag = imag;
}
Complex(double d = 0.0) // 转换构造函数
{
this->real = d;
this->imag = 0;
}
Complex operator+(Complex com1);
void PrintMessage();
};
Complex Complex::operator+(Complex com1) // +的重载
{
return Complex(real + com1.real, imag + com1.imag);
}
void Complex::PrintMessage()
{
cout << real;
if (imag > 0) cout << "+";
if (imag != 0) cout << imag << "i" << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Complex com(10, 10);
Complex sum;
sum = com + 5.5;
sum.PrintMessage();
return 0;
}
运行结果:
在执行“+”的时候执行了运算符重载函数,执行5.5的时候,执行了转换构造函数,将5.5转换为Complex类
注:转换构造函数不仅能将系统预定义数据类型转换为自定义类对象,还可以将其他类对象转化为所在的类的类对象,但是不能把类对象转化为基本的数据类型
c++中的类型转换函数却可以将类对象转化为基本的数据类型
⑤使用类型转换函数进行转换,使其与某一重载函数匹配(代码Ⅵ)
定义类型转换函数的一般形式:
operator 目标类型()
{
...
return 目标数据类型
}
目标类型是所要转化成的类型名,既可以是预定义及基本类型也可以是自定义类型。
类型转换函数的函数名(operator 目标类型)前不能指定返回类型
没有参数
但在函数体最后一条语句一般为return语句,返回的是目标类型的数据。
代码Ⅵ:
// 转换构造函数和类型转换函数.cpp : 定义控制台应用程序的入口点。
// 我们在此处定义一个复数类
#include "stdafx.h"
class Complex
{
private:
double real;
double imag;
public:
Complex(double real, double imag)
{
this->real = real;
this->imag = imag;
}
Complex(double d = 0.0) // 转换构造函数
{
this->real = d;
this->imag = 0;
}
Complex operator+(Complex com1);
void PrintMessage();
operator double(); //类型转换函数
};
Complex Complex::operator+(Complex com1) // 运算符重载函数
{
return Complex(real + com1.real, imag + com1.imag);
}
Complex::operator double() //类型转换函数
{
return real;
}
void Complex::PrintMessage()
{
cout << real;
if (imag > 0) cout << "+";
if (imag != 0) cout << imag << "i" << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
Complex com(10, 10);
double sum1, sum2;
sum1 = 5.5 + com; // 隐式转换
sum2 = double(com) + 5.5; //显式转换
cout << "sum1=" << sum1 << endl;
cout << "sum2=" << sum2 << endl;
return 0;
}
sum1 = 5.5 + com; // 隐式转换
这儿只能是5.5+com而不能是com+5.5,否则编译器过不了,因为在这会出现歧义不知道是com转化为double进行double的加法还是5.5转化为Complex进行Complex的加法