C++中的函数
作者:互联网
1、C++内联函数
内联函数是C++为提高运行速度所做的一项改进。内联函数在函数声明前加上关键字inline,在函数定义前加上关键字inline。
1.1 内联函数与宏
inline工具是C++新增的特性。C语言使用预处理器语句#define来提供宏——内联代码的原始实现。
定义一个宏:#define SQUARE(X) X*X
这并不是通过传递参数实现的,而是通过文本替换来实现的——X是“参数”的符号标记。
a=SQUARE(5.0); 替换成 a=5.0*5.0;
b=SQUARE(4.5+7.5); 替换成b=4.5+7.5*4.5+7.5;
d=SQUARE(C++); 替换成d=C++*C++;
上述示例只有第一个能正常工作。可以通过使用括号来进行改进:
#define SQUARE(X) ((X)*(X))
但是仍然存在这样的问题,即宏不能按值传递。即使使用新的定义,SQUARE(C++)仍将C递增两次。
内联函数:
inline double square(double x) {return x*x; }
2、引用
#include <iostream>
#include <string>
struct free_throws
{
std::string name;
int made;
int attempts;
float percent;
};
//传递引用,不允许更改结构内容
void display(const free_throws& ft);
void set_pc(free_throws& ft);
free_throws& accumulate(free_throws& target, const free_throws& source);
int main()
{
free_throws one = { "Ifelsa Branch", 13, 14 };
free_throws two = { "Andor Knott",10,16 };
free_throws three = { "Minnie Max",7,9 };
free_throws four = { "Whily Lopper",5,9 };
free_throws five = { "Long Long",6,14 };
free_throws team = { "Throwgoods",0,0 };
free_throws dup;
set_pc(one);
display(one);
accumulate(team,one);
display(team);
dup = accumulate(team, five);
std::cout << "Display team:\n";
display(team);
std::cout << "Displaying dup after assignment:\n";
display(dup);
set_pc(four);
accumulate(dup,five)=four;
std::cout << "Displaying dup after ill-advised assignment:\n";
display(dup);
std::cin.get();
return 0;
}
void display(const free_throws& ft)
{
std::cout << "Name: " << ft.name << std::endl;
std::cout << "-Made: " << ft.made << '\t';
std::cout << "Attempts: " << ft.attempts << '\t';
std::cout << "Percent: " << ft.percent << '\n';
}
void set_pc(free_throws& ft)
{
if (ft.attempts != 0)
ft.percent = 100.0f*float(ft.made) / float(ft.attempts);
else
ft.percent = 0;
}
free_throws& accumulate(free_throws& target, const free_throws& source)
{
target.attempts += source.attempts;
target.made += source.made;
set_pc(target);
return target;
}
运行结果:
程序中的语句:
accumulate(dup,five)=four;
这条语句将赋值给函数调用,这是可行的,因为函数的返回值是一个引用。如果函数accumulate()按值返回,这条语句不能通过编译。由于返回的是指向dup的引用,因此上述代码与下面的代码等效:
accumulate(dup,five);
dup=four;
2.1 为什么要返回引用
free_throws dup;
dup=accumulate(team,five);
如果accumulate()返回一个结构,而不是指向结构的引用,将把整个结构复制到一个临时位置,再将这个拷贝给dup。但在返回值为引用时,将直接把team复制到dup,其效率更高。
返回引用时应该避免返回函数终止时不再存在的内存单元引用。应该避免下面这样的代码:
const free_throws& clone2(free_throws& ft)
{
free_throws newguy;
newguy=ft; //拷贝赋值
return newguy;
}
该函数返回一个指向临时变量(newguy)的引用,函数运行完毕后它将不再存在。
3、函数重载
函数重载能够使用多个同名的函数,函数重载的关键是函数参数列表——也称为函数特征标。如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则它们的特征标相同,而变量名是无关紧要的,C++允许定义名称相同的函数,条件是他们的特征标不同。
4、函数模板
函数模板是通用的函数描述,也就是说,它们使用泛型来定义函数,其中的泛型可用具体的类型替换,通过将类型作为参数传递给模板,课时编译器生成该类型的函数。函数模板不能缩短可执行程序,最终的代码不包含任何模板,而只包含了为程序生成的实际函数。使用模板的好处是,它使生成多个函数定义更简单、更可靠。
更常见的形式是将模板放在头文件中,并在需要使用模板的文件中包含头文件。
4.1 重载模板
需要多个对不同类型使用同一种算法的函数时,可使用模板。和常规重载一样,被重载的模板的函数特征值必须不同。
4.2 显式具体化
提供一个具体化函数定义——称为显式具体化,其中包含所需的代码。当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再寻找模板。
- 对于给定函数名,可以有非模板函数、模板函数和显式具体化模板函数以及它们的重载版本。
- 显式具体化的原型和定义应以template<>打头,并通过名称来指出类型。
- 具体化优先于常规模板,而非模板函数优先于具体化和常规模板。
下面是用于交换结构的非模板函数、模板函数和具体化的原型:
struct job
{
char name[40];
double salary;
int floor;
};
void Swape(job&, job&); //非模板函数
template <typename T>
void Swap(T&, T&); //模板函数
template <> void Swap<job>(job&, job&); //具体化原型
编译器在选择原型时,非模板版本优于显式具体化和模板版本,而显式具体化优于使用模板生成的版本。
关键字decltype(C++11)
C++11新增的关键字decltype确定变量的类型。
template <class T1, class T2>
void ft(T1 x, T2 y)
{
decltype(x+y) xpy=x+y;
}
标签:函数,free,C++,具体化,throws,模板 来源: https://blog.csdn.net/qq_41455814/article/details/121022775