关键字static
在这一章节,将对C++中的关键字static做进一步介绍。
成员函数中的this指针
这里先附上之前写的一个complex类代码:
//防卫式定义
#ifndef __MYCOMPLEX__
#define __MYCOMPLEX__
//前置声明
class complex;//类声明
complex& __doapl (complex* ths, const complex& r);//函数声明
complex& __doami (complex* ths, const complex& r);
complex& __doaml (complex* ths, const complex& r);
class complex{//函数定义
public:
complex (double r = 0, double i = 0): re (r), im (i) { }//构造函数
complex& operator += (const complex&);//操作符重载+=
complex& operator -= (const complex&);//操作符重载-=
complex& operator *= (const complex&);//操作符重载*=
complex& operator / = (const complex&);//操作符重载/=
double real () const { return re; }//获取实部
double imag () const { return im; }//获取虚部
private:
double re, im;//成员变量一般写在私有保护区
friend complex& __doapl (complex *, const complex&);//友元函数
friend complex& __doami (complex *, const complex&);
friend complex& __doaml (complex *, const complex&);
};
#endif //__MYCOMPLEX__
我们知道,一个类中的成员函数的形参,默认情况下存在this指针,虽然你不能显式的把这个指针给写在形参列表里,但可以在成员函数中显式或隐式的使用它。例如:
double real () const
{
return re;
}//这段代码和下面这段代码作用一样
double real () const
{
return this->re;
}
我们正常情况下是如何调用这个函数的?
complex c1,c2,c3;
cout<< c1.real();
cout<< c2.real();
而C++是如何知道它实际返回的应该是那个real呢?正是通过this参数,换个说法,上面那段代码也可以理解成这样:
complex c1,c2,c3;
cout<< complex::real(&c1);
cout<< complex::real(&c2);
在这里函数里面的形参实参&c1实际上便是我们成员函数中那个看不见的形参this指针。
于是,我们可以推理出来:this指针的其中一个实际作用便是:让某个class的具体对象在调用(非静态)类成员函数的时候能够得到对应对象的数据,而不是其他对象的。
好了,有个这个结论将会帮助你进一步的了解static的作用。
static的特性
现在,我们给上面的complex类加上static:
静态成员与静态成员函数
对于加了static的静态成员来讲,这个成员已经跟对象脱离了,不再属于某一个具体的对象,它单独的在内存中有一个区域存储,且该数据只有一份。对于静态成员函数也是如此:内存中有且只有一份这样的静态成员函数。
静态成员函数与普通成员函数
静态成员函数与普通成员函数的差别就是静态成员函数没有this指针。而根据我们前面得出的那个结论,如果静态成员函数中没有this指针,也就意味着它无法去处理以后根据这个类实例化出来的各个对象的具体数据。换言之,静态成员函数只能处理静态成员数据。这是最根本的不同。
语法上的特性
class Account
{
public:
static double m_rate;
static void setRate(const double& x)(m_rate = x;)
};
double Account::m_rate = 8.0;
int main()
{
Account::setRate(5.0);
Account a;
a.setRate(7.0);
}
这里,static的语法上的特性主要有两条:
- static成员必须在class外定义;
- 调用static成员函数的形式有两种:
- 通过class name去调用;
- 通过object调用;