8.1C++内联函数
内联函数,编译器将使用相应的函数代码替换函数调用,程序无需跳到另一个位置处执行代码,在跳回来。因此,内联函数运行速度更快,但是需要占用更多内存。
- 在函数声明和定义前加关键字inline
- 不能做递归函数
C语言使用预处理器语句#define来提供宏----内联函数的原始实现。
#define SQUARE(X) X*X;
inline double square(double x) {return x*x};
内联函数更安全。比如a = SQUARE(c++); //is replaced by d=c++*c++;
8.2 引用变量
int rats;
int &rodents = rats;
rodents rats指向相同的值和内存单元
引用创建时必须初始化。
右值引用(需要研究一下)
返回引用,要避免返回函数终止时不再存在的内存单元引用。
const free_throws &clone2(free_throws &ft)
{
free_throws newguy;
newguy = ft;
return newguy;
}
有两种常规方法避免上述问题:
1、返回一个作为参数传递给函数的引用。
free_throws &accumulate(free_throws &target,const free_throws &source)
{
target.attempts += source.attempts;
target.made += source.made;
set_pc(target);
return target;
}
2、用new来分配新的储存空间。这种方法需要手动delete内存,容易忽略。
const free_throws &clone(free_throws &ft)
{
free_throws *pt;
*pt = ft;
return *pt;
}
const 用于引用返回类型
accumulate(dup,five) = four;
函数返回值指向dup的引用,时一个可修改的内存,因此这条语句合法。常规函数返回值位于临时内存单元中,运行到下一条语句可能不再存在。
要使用引用返回值,但又不允许上述函数赋值操作,将返回类型声明为const即可。
const free_throws &accumulate(free_throws &target,const free_throws &source)
对象、继承和引用
示例代码
#include <iostream>
#include <fstream>
#include <cstdlib>
using namespace std;
void file_it(ostream &os,double fo,const double fe[],int n);
const int LIMIT = 5;
int main()
{
ofstream fout;
const char *fn = "ep-data.txt";
fout.open(fn);
if(!fout.is_open())
{
cout << "Can't open " << fn << endl;
exit(EXIT_FAILURE);
}
double obj;
cout << "Enter the focal length os your ";
cin >> obj;
double eps[LIMIT];
for(int i=0;i<LIMIT;i++)
{
cout << "Eyepiece #" << i+1 << ": ";
cin >> eps[i];
}
file_it(fout,obj,eps,LIMIT);
file_it(cout,obj,eps,LIMIT);
fout.close();
cout << "Done\n";
return 0;
}
void file_it(ostream &os,double fo,const double fe[],int n)
{
ios_base::fmtflags initial;
initial = os.setf(ios_base::fixed); //将对象置于使用定点表示法的模式
os.precision(0);
os <<"Focal length of obj:" << fo << " mm\n";
os.setf(ios::showpoint); //显示小数点模式
os.precision(1); //显示1位小数点
os.width(12); //设置下一次输出使用的字段宽度
os << "f.1. eyepiece";
os.width(15);
os <<"magnification" << endl;
for(int i=0;i<n;i++)
{
os.width(12);
os << fe[i];
os.width(15);
os << int(fo/fe[i] + 0.5) << endl;
}
os.setf(initial);
}
运行结果:
Enter the focal length os your 4
Eyepiece #1: 1.1
Eyepiece #2: 2.2
Eyepiece #3: 3.3
Eyepiece #4: 4.4
Eyepiece #5: 5.5
Focal length of obj:4 mm
f.1. eyepiece magnification
1.1 4
2.2 2
3.3 1
4.4 1
5.5 1
Done
8.3默认参数
char* left(const char* str,int n=1);
对于带参数列表函数,必须从右向左添加默认值。
int harpo(int n,int m=4,int j=5) //有效
int harpo(int n,int m=4,int j) //无效
8.4函数重载
类型引用和类型本身不能作为重载函数
double cube(double x);
double cube(double &x);
8.5函数模板
template <typename AnyType>
void Swap(AnyType &a,AnyType &b)
{
AnyType temp;
temp = a;
a = b;
b = temp;
}
显示具体化:
#include <iostream>
template <typename T>
void Swap(T &a,T &b);
struct job
{
char name[40];
double salary;
int floor;
};
template <> void Swap<job>(job &j1,job &j2);
void Show(job &j);
int main()
{
using namespace std;
cout.precision(2);
cout.setf(ios::fixed,ios::floatfield);
int i=10,j=20;
cout << "i,j=" << i << "," << j << ".\n";
cout << "using compiler generated int swapper:\n";
Swap(i,j);
cout << "Now i,j = " << i << "," << j << ".\n";
job sue = {"Susan Yaffee",73000.60,7};
job sidey = {"Sidney Taffee",78060.72,9};
cout << "before job swappong\n";
Show(sue);
Show(sidey);
return 0;
}
template <typename T>
void Swap(T &a,T &b)
{
T temp;
temp = a;
a = b;
b = temp;
}
template <> void Swap<job>(job &j1,job &j2)
{
double t1;
int t2;
t1 = j1.salary;
j1.salary = j2.salary;
j2.salary = t1;
t2 = j1.floor;
j2.floor = j1.floor;
j1.floor = t2;
}
void Show(job &j)
{
std::cout << j.name << " :$" << j.salary << " on floor" << j.floor << std::endl;
}
运行结果:
i,j=10,20.
using compiler generated int swapper:
Now i,j = 20,10.
before job swappong
Susan Yaffee :$73000.60 on floor7
Sidney Taffee :$78060.72 on floor9
显示实例化:template void Swap<int>(int ,int);
具体实例化:template <> void Swap<int>(int &,int &); 或者 template <> void Swap(int &,int &);