一、内联(inline)
以inline修饰的函数叫内联函数,编译时c++编译器会在调用内联函数的地方将其展开,没有函数压栈的开销,内联函数提升程序运行的效率。
- inline时一种以时间换空间的做法,省去调用函数的开销,所以代码很长或内部有循环,递归的函数不适宜使用内联
- inline对编译器只是一个建议,编译器会自动优化。如果定义为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联
- inline必须和函数的定义放在一起,才能称为内联函数,仅将inline放在声明前时不起作用的
- 定义在类内的成员函数默认为内联函数
class Date
{
public:
void Func()//定义在类内的函数默认为内联函数
{}
void Display();
private:
int _year;
int _month;
int _day;
};
inline void Date::Display()//成员函数类外定义为内联
{
cout << "year:" << _year << endl;
cout << "month:" << _month << endl;
cout << "day:" << _day << endl;
}
inline void Test()//全局函数定义为内联
{}
尽量使用const,enum,inline替换#define,为什么?
宏的优点:
- 代码的复用性强
- 可以提高程序的性能
宏的缺点:
- 不能调试(预处理阶段即进行了替换)
- 没有类型检查
- 可读写差,可维护性差
而#define定义的常量我们可以用const,enum代替,#define定义的宏我们可以用inline进行替换,他们有着宏的优点,却不具备宏的缺点。c++通过内联机制,既具备宏代码的效率,又增加了安全性,还可以资源操作类的数据成员,算是一个比较完美的解决方案
inline和宏的区别:
- 内联函数和宏一样,将在被调用处进行代码展开,省去了参数压栈,栈帧开辟回收的开销,从而提高了程序的运行速度
- 内联函数相比宏来说,在代码展开时,会做安全检查或自动类型转化,而宏定义没有参数类型检查。
- 在类中声明同时定义的成员函数默认为内联函数,使用内联函数可以访问雷达成员变量,宏定义则不能。
- 内联函数在运行时可以调试,而宏定义不能
二、友元(friend)
友元函数:
在C++中友元函数允许在类外访问该类中的任何成员,就像成员函数用于,友元函数用关键字friend声明
- 友元函数不是类的成员函数
- 友元函数可以通过对象访问使用成员,私有和保护成员也一样
class Date
{
friend void Display(const Date &d);//定义为友元
private:
int _year;
int _month;
int _day;
};
void Display(const Date &d)//类外访问其私有成员
{
cout << "year:" << d._year << endl;
cout << "month:" << d._month << endl;
cout << "day:" << d._day << endl;
}
void Test()
{
Date d1;
Display(d1);
}
输入输出运算符的友元函数
1.类中只要六个成员函数在不得已时会默认生成,其余的如<<, >>要使用的话,必须重载
2.operator<<可以定义为成员函数吗?
- 可以将其放在类内定义,但是调用时的方式为d1.operator<<(cout)不符合我们常规的输出方式,所以建议在类外定义
定义在类内:
如果按我们的输出方式输出的话会报错:
所以建议定义在类外
class Date
{
public:
friend ostream & operator<< (ostream& os, const Date& d);
friend istream & operator>>(istream& is, const Date& d);
private:
int _year;
int _month;
int _day;
};
ostream & operator << (ostream& os, const Date& d)
{
os << "year:" << d._year << endl;
os << "month:" << d._month << endl;
os << "day:" << d._day << endl;
return os;
}
istream & operator>> (istream& is, const Date& d)
{
cout << "请输入年月日" << endl;
is >> d._year;
is >> d._month;
is >> d._day;
return is;
}
3.operator<<函数的返回值,可以是void吗?
- 不可以,因为我们要实现链式输出,所以要用ostream&,istream&
友元类:
整个类可以是另一个类的友元,友元类的每个成员函数都是另一个类的友元函数,都可以访问另一个类中的保护或者私有的数据成员
class Time
{
friend class Date;//Date是Time的友元,它可以访问Time的私有成员
private:
int _hour;
int _minute;
int _second;
};
class Date
{
public:
void Display()
{
cout << _year << endl;
cout << _month << endl;
cout << _day << endl;
cout << _t._hour << endl;
cout << _t._minute << endl;
cout << _t._second << endl;
}
private:
int _year;
int _month;
int _day;
Time _t;
};
友元一定程度上破坏了c++的封装性,所以要用在适当的地方