static关键字在c/c++中的作用
static在c语言中有三个作用:
修饰函数
修饰局部变量
修饰全局变量
- 被static修饰的全局变量被称之为静态全局变量。静态全局变量和全局变量在存储方式上是一致的,都储存在数据段,编译阶段分配内存空间,在程序结束时释放。但是,对于多文件的程序来说,静态全局变量只在定义该变量的源文件内有效,也就是我们常说的它具有隐身属性。
- 对于修饰局部变量:当一个局部变量被static修饰后,它就类似于是一个全局变量,程序结束时才释放,它也储存在数据段
- 对于修饰函数:static函数与普通函数作用域不同,仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static修饰的函数),内部函数应该在当前源文件中说明和定义。这样做的好处是:其他文件中可以定义相同的名字,防止命名冲突.静态函数不能被其他文件所用
static在c++中的作用:
- 修饰类的成员函数
- 修饰类的成员变量
有一个需求:我们想知道一个程序创建了几个对象:
int _count=0;
class Date
{
public:
Date(int year = 1900, int month = 1, int day = 1)
: _year(year)
, _month(month)
, _day(day)
{
_count++;
cout << "Date(int,int,int):" << this << endl;
}
Date(Date& d)
: _year(d._year)
, _month(d._month)
, _day(d._day)
{
++_count;
cout << "Date(const Date&):" << this << endl;
}
Date& operator=(const Date& d)
{
cout << this << "=" << &d << endl;
if (this != &d)
{
_year = d._year;
_month = d._month;
_day = d._day;
}
return *this;
}
~Date()
{
cout << "~Date():" << this << endl;
_count--;
}
private:
int _year;
int _month;
int _day;
};
void TestDate()
{
Date d1(2020,10,18);
Date d2(d1);
}
int main()
{
Date d(2020, 10, 18);
TestDate();
return 0;
}
每次创建一个对象,就要调用构造函数,_count就会++,每次对象生命周期结束,对象要被销毁,调用析构函数,_count–
但是在主函数中还是可以修改全局变量的值,导致代码不安全,为了防止这种现象,我们就引入了静态成员这一概念。
静态成员:被static修饰的成员称之为静态成员,静态成员变量是所有的对象共享的,且静态成员变量并不包含在对象中(不占据对象的内存空间),它是类的一个属性,并不是单独一个对象的属性。
注意:静态成员变量在类里边只能算是一种声明,如果要初始化必须要在类外,它不能在构造函数初始化列表进行初始化
静态成员变量有两种访问方式:
Date d0;
cout << d0._count << endl;
cout << Date::_count << endl;
①对象.的方式,这种方式如果单独的为了访问静态成员变量就得多创建一个对象出来,不太方便,所以还有第二种访问方式
②域解析操作符,Date::_count,这种方式可以直接通过类来对静态成员变量进行访问,二者在底层的实现是相同的。
什么是静态成员函数?
答:被static修饰的成员函数称之为静态成员函数,他和普通成员函数的区别是既可以通过对象.的方式调用,也可以通过域解析操作符直接新型访问(前提是该静态成员函数必须是public),即双重保险(public:static)。
所以,被private修饰的成员(不论是成员变量还是成员函数),不论是对象.的方式还是类的与解析操作符的方式,都不能在类外进行访问,但初始化静态成员变量是一个例外,因为静态成员变量一定要初始化,且只能在类外初始化。
静态成员函数参数中是没有this指针的,所以它不能被const来修饰
- 因为const修饰的类成员函数本质并不是在修饰函数,而是在修饰函数隐藏的参数 *this,既然static修饰的成员函数没有this指针,所以它不能被const修饰
- 同理: 拷贝构造函数,赋值运算符重载,构造函数不能被static来修饰
- 静态成员函数不能调用非静态成员函数,但是非静态成员函数可以调用静态成员函数。因为静态成员函数没有对象,即:有对象可以调用没对象,没对象不能调用有对象
静态成员函数作用:
不属于类对象,所以可以不通过对象而执行,但逻辑上属于类,实现数据封装,
并且1.提供一种方式访问静态成员变量
2.避免使用全局函数,为函数设置一个类域的访问权限
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)