一 内联函数:
与一般函数相比,编码的方式相同,不同的地方在于函数的调用机制。
这是C++为了提高函数的运行效率所创建。
内联函数的声明: inline 返回值类型 函数名(参数列表)。
其运行的机制就是在于,当调用内联函数时,直接将函数的代码复制到调用的函数的地方
这个方法适合小型函数的使用,否则大型函数的直接复制,将很浪费时间和资源。
此处C++的内联函数类似于C语言中的宏定义的功能,如:
#define N 6 相当于在以后使用 N 时,都会自动替换成 6
#define sum(num) num + num 相当于以后再调用 sum(num) 时,等于调用 num + num
如图,内联函数的声明和调用方法如下所示:
内联函数的定义方法: 在函数声明是加 inline, 或者是在函数实现时加 inline
二 reference 引用 相当于为对象起了一个别名
int value = 99;
int& refvalue = value; refvalue指向value是其另一个名字,所以以后操作refvalue的时候,等于操作value
注意:定义引用的时候,必须进行初始化,不可以直接引用常量
错误:int& refvalue = 5;
如果想要引用常量,可以定义为:
const int& refvalue = 6;
当使用引用变量时,相当于直接使用原始数据,而不是副本,相当于 const 指针
引用和指针的使用实例:
# include <iostream>
using namespace std;
void Swap1(int&, int&);
void Swap2(int*, int*);
int main()
{
int num1 = 5, int num2 = 50;
Swap1(&num1, &num2);
Swap2(num1, num2);
return 0;
}
void Swap1(int& num1, int& num2) 使用引用来作为参数进行交换
{
int temp;
temp = num1;
num1 = num2;
num2 = temp;
return;
}
void Swap2(int* num1, int* num2) 使用指针作为参数进行交换
{
int temp;
temp = *num1;
*num1 = *num2;
*num2 = *num1;
return;
}
使用引用的好处:1 可以更加简便的书写代码 2 直接传递对象, 而不是复制一个副本
三 函数的返回值是引用类型
1. 不要返回局部变量的引用,因为变量有自己的生存周期,
当函数结束时,函数内部声明的变量就会被回收。所谓的内存回收,并不是销毁内存中原有的数据,
而是指,这块内存不在归本函数使用,其他的函数可以对这块内存进行修改,
就像,租房子的时间到了,要把房子进行归还,新住进来的人将会改变房子中的内容。
2. 函数可以没有返回值 当函数返回为引用类型是,必须是参数列表中的某个参数,
假设函数的声明: int &sum(int& num1, int& num2)
不能返回 return num1 + num2; 只能返回 num1 或者是 num2
3. 如果定义的函数返回类型为引用类型, 为了保险,要在函数的声明部分加 const
const int& sun(int&, int&); 防止出现 sum(num1, num2) = 88; 这样的模糊定义
#include <iostream>
#include "reference.hpp"
using namespace std;
int &sum(int&, int&);
int main()
{
int num1 = 5, num2 = 10;
int& result = sum(num1, num2);
cout << "result = " << result << endl;
return 0;
}
int &sum(int& num1, int& num2) 当函数没有设置返回值的时候,默认返回最后一个变量的引用
{
num1 = 5;
num2 = 6; 可以没有返回值
}
四. 按值传递、按指针传递和按引用传递,在函数使用方面三者怎么选择。
1. 使用引用传递的时候,可以修改对象的内容
2. 数据对象较大时,传递引用可以增加效率
3. 当函数中不需要进行对象内容的修改时
如果数据对象很小,则建议按值进行传递
传递数组的时候,只能用指针传递
数据对象很大时,建议使用 const 指针或引用 以提高运行的效率
4. 需要修改数据对象是
数据对象是基本类型或者是结构的时候,可以使用指针或者是引用(基本类型建议指针)
数据必须使用指针
类的对象作为数据对象时,最好使用引用传递
五、 使用默认参数
void sum(int num = 10);
void sum(int sum) 此处不能再赋值 错误写法:void sum(int sum = 10);
{
cout << sum <<endl;
}
注意: 1 使用默认函数时,声明和实现部分只能有一个赋值
2 参数列表有多个参数时,在给默认参数进行赋值时,只能从右往左进行赋值
正确的写法: void sum(int a, int b = 10, int c = 10);
正确的调用: sum(1); sum(1, 2); sum(1, 2, 3);
错误的写法: void sum(int a = 10, int b, int c = 10);
六 函数的重载
所谓函数的重载就是 多个函数,函数名相同,但是参数列表不同,比如:
void num(int num1, int num2); void num(double num1, double num2);
voie num(int num1); void num(double num1);
注意: void sum(int&) 和 void sum(int) 是一样的,因为在调用的时候,都是一样的
比如: void sum(10); 这样的话就会报错,因为编译器不知道你调用的到底是哪个函数
实际上,在函数内部进行调用的时候,是根据特征标来进行函数的调用
比如 void sum(int); 和 void sum(float);是函数的重载
但在执行的时候,编译器 重载决议 将 void sum(int); 编译为 void sum_int
同理将 void sum(float); 编译为 void sum_float
所以实际上 void sum(int&) 和 void sum(int) 在编译时,都会编译为
void sum_int
七 利用函数的重载进行对不同类型的数组排序
main函数部分:
#include <iostream>
#include "sort.hpp"
using namespace std;
int main()
{
int intArry[6] = {11, 66, 55, 44, 33, 22};
double doubleArray[6] = {11.1, 44.4, 55.5, 66.6, 22.2, 33.3};
Show(intArry, 6); 显示排序前的数组
Sort(intArry, 6); 对数组进行排序
Show(intArry, 6); 再次显示
Show(doubleArray, 6);
Sort(doubleArray, 6);
Show(doubleArray, 6);
return 0;
}
排序的 sort.hpp 部分:
#ifndef SORT_HPP_INCLUDED
#define SORT_HPP_INCLUDED
#include <iostream>
using namespace std;
void Sort(int [], int); 利用函数的重载进行排序
void Sort(double [], int);
void Show(int [], int); 利用函数的重载进行显示
void Show(double [], int);
#endif // SORT_HPP_INCLUDED
排序的 sort.cpp 部分:
#include <iostream>
#include "sort.hpp"
using namespace std;
void Sort(int Array[], int Length) 对int型的函数进行排序
{
for(int i = 0; i < Length - 1; i++)
{
for(int j = 0; j < Length - 1 - i; j++)
{
if(Array[j] > Array[j + 1])
{
int temp;
temp = Array[j];
Array[j] = Array[j + 1];
Array[j + 1] = temp;
}
}
}
return;
}
void Sort(double Array[], int Length) 对double型的函数进行排序
{
for(int i = 0; i < Length - 1; i++)
{
for(int j = 0; j < Length - 1 - i; j++)
{
if(Array[j] > Array[j + 1])
{
double temp;
temp = Array[j];
Array[j] = Array[j + 1];
Array[j + 1] = temp;
}
}
}
return;
}
void Show(int Array[], int Length) 对int型的函数进行排序
{
for(int i = 0; i < Length; i++)
{
cout << Array[i] << '\t';
}
cout << endl;
return;
}
void Show(double Array[], int Length) 对double型的函数进行显示
{
for(int i = 0; i < Length; i++)
{
cout << Array[i] << '\t';
}
cout << endl;
return;
}
函数重载的意义:用同一个函数名,实现对不同数据类型的数组进行排序和显示
缺点: 代码的重复率过高,不简洁
八 函数模板
一般函数模板的声明:template <typename T> void sum(T num1);
其中T是一个虚拟的数据类型,会根据传入的实参而改变。
所谓函数模板,实际上就是建立一个通用函数
1. 函数定义时,不指定具体的数据类型(使用虚拟类型来代替)
2. 函数在调用的时候,编译器会根据传入的实参来反推数据类型--类型的参数化
注意:在声明模板函数的时候,模板函数的声明和实现必须都放在同一个文件夹中,不能分文件操作。
模板函数的优点: 与函数的重载相比,减少了代码量,只需书写一个函数模板就可以实现
对不同数据类型的操作
比如,用函数模板实现对不同数据类型的数组进行显示 :
#include <iostream>
#include "sort.hpp"
using namespace std;
template <typename T>
void TShow(T TArray[], int Length)
{
for(int i = 0; i < Length; i++)
{
cout << TArray[i] << '\t';
}
cout << endl;
}
int main()
{
int intArray[] = {11, 66, 55, 44, 33, 22};
double doubleArray[] = {11.1, 44.4, 55.5, 66.6, 22.2, 33.3};
TShow(intArray, sizeof(intArray) / sizeof(intArray[0]));
TShow(doubleArray, sizeof(doubleArray) / sizeof(doubleArray[0]));
return 0;
}
使用场合:
在不同类型的数据有相同操作的时候,用函数模板,如果不同数据的操作不同,采用函数重载
因为函数模板只有在业务逻辑一样,但是数据类型不一样的情况下才能使用。
未完待续~~~