首先,重载已经在上一篇博客里面有简单的介绍,这篇博客来简单说一下重载“<<”操作符。
当我第一次想到重载“<<”操作符的时候,想法和重载其他的操作符是一样的想法,实现的代码如下:
class Date
{
public:
void operator<<(ostream &_cout);
Date(int year,int month,int day)
:_year(year)
,_month(month)
,_day(day)
{}
private:
int _year;
int _month;
int _day;
};
void Date::operator<<(ostream &_cout)
{
_cout<<_year<<"-"<<_month<<"-"<<_day<<endl;
}
但是,这个重载调用的时候却是能这样调用:
int main()
{
Date today(2017,9,14);
today<<cout;
return 0;
}
虽然,
这个重载完成了基本的功能,但是这样的调用不符合平时编写代码的习惯,而且在我们写代码的时候经常会用到连续的输出,显然这个函数没有达到我们想要的目的,同时在重载的内部含有换行操作,这是一个不好的设计方式,不建议在重载的内部换行。
于是,重新对重载进行了设计,
friend ostream & operator<<(ostream &_cout,Date &d)
{
_cout<<d._year<<"-"<<d._month<<"-"<<d._day;
return _cout;
}
当我们这样设计重载的时候就可以和习惯性的调用那样进行调用,并且这个重载友元函数还可以进行连续的调用。
static关键字的常见用法:
在c语言里面,static关键字可以修饰全局变量、函数、局部变量:
(1)、当个修饰全局变量的时候,会将全局变量存储在静态区,这样就变成了静态全局变量,作用域为整个文件的作用域(整个程序运行期间都存在),在没有显示的对静态全局变量进行初始化的时候,编译器会自动 的给我们初始化成0.
(2)、当static修饰局部变量的时候,就变成局部静态变量,作用域为局部作用域(在函数或者语句模块调用期间)。
(3)、当static修饰函数的时候、直接的改变了函数的链接属性,将函数的外部链接属性改成了局部链接属性,即普通函数可以由extern声明为外部链接属性,但是static修饰的函数只能在本文件的作用域内进行使用。
在c语言里面使用static修饰主要就是改变变量的生命周期和作用域。
在C++里面出来可以兼容c语言里面的用法同时还可以修饰成员变量和成员函数:
(1)、static修饰成员变量时候,这个变量并不占用这个对象的大小!
class Date
{
private:
int _year;
int _month;
int _day;
static int data;
};
int main()
{
cout<<sizeof(Date)<<endl;
return 0;
}
这个程序的运行结果是
12
,但是为什么会是这样?
在用每个类创建对象的时候,static修饰的变量是创建在代码段的公共存储区,即无论用这个类创建对少个对象,任何一个对象访问这个变量都是访问的同一个位置。
那么就存在另外一个性质:无论是用类名::static变量还是对象.static变量,其结果都是一样的,他们访问的都是同一个地址。
(2)、static修饰成员函数的时候。
在每个对象调用成员函数的时候间接的使用this指针进行的,但是在static修饰的成员函数里面不存在this指针,所以在static函数里面不能调用非静态变量,而在非静态成员函数里面可以调用静态成员变量。
为什么在静态成员函数里面不可以调用非静态成员变量?
首先,每个对象调用成员函数的时候是通过this指针来实现的,但是在static成员函数里面是没有this指针的,所以在静态成员函数里面是不可以访问非静态成员变量。
为什么在非静态成员函数里面可以访问静态成员变量?
静态成员变量存储在代码段的公共存储区,在这里是每个对象都可以访问的位置,所以在非静态成员函数里面可以访问静态成员变量,并且每个对象访问的位置和值都是一样的。