C语言到C++(7) - static
![](https://img.haomeiwen.com/i145902/48db7847c747491d.jpg)
static这个关键字我们在C语言的学习中已经遇到过了。在C++中,它又被赋予了一些新的功能。
1. static在C语言中的用法
1.1 修饰全局变量
C语言的所有源文件的内容在编译时会被组织成一个逻辑文件进行编译的。这就会使一个文件的全局变量可以被程序的任意位置访问到。例如:
- 文件file1.h
#ifndef __FILE1_H__
#define __FILE1_H__
void function();
#endif
- 文件file1.c
#include "file1.h"
int a = 0;
void function()
{
printf("a = %d", a);
}
- 文件main.c
#include <stdio.h>
#include "file1.h"
int a = 1;
int main()
{
printf("a = %d", a);
return 0;
}
这三个文件编译时会报错,因为编译器认为定义了两个全局变量a
。
首先,这种定义两个同名变量的方法是不可取的,它会严重影响代码的可读性。如果由于某些特殊原因一定要这样设计的话,可以修改文件file1.c
如下:
#include "file1.h"
static int a = 0;
void function()
{
printf("a = %d", a);
}
这样就能够正确编译了。因为加了static
修饰的变量a
只在文件file1.c
中起作用。
1.2 修饰函数
和1.1相似,如果我们把function
函数定义改为:
static void function()
{
printf("a = %d", a);
}
这样,在文件main.c
中就无法调用这个函数了。大家可以自己验证一下。
1.3 修饰局部变量
我们来看看这段程序:
#include <stdio.h>
void function()
{
int a = 0;
printf("a = %d\n", a++);
}
int main()
{
function();
function();
function();
return 0;
}
执行结果如下:
![](https://raw.githubusercontent.com/breakerthb/CloudIDE_WB/master/PicBed/2017/1502769490.png)
这个大家一定都能看懂,但如果改成这样呢?
#include <stdio.h>
void function()
{
static int a = 0;
printf("a = %d\n", a++);
}
int main()
{
function();
function();
function();
return 0;
}
执行结果是这样的:
![](https://raw.githubusercontent.com/breakerthb/CloudIDE_WB/master/PicBed/2017/1502769650.png)
由于变量a
被定义为static
的,因此每次调用之后它的值会被记录下来,生命周期并没有结束。
接下来我们来看看在C++中,static
究竟新加入了那些功能。
2. 静态成员变量
在C++的类的每个对象中,都有一组独立的成员变量,我们可以对他们分别赋值,它们相互之间没有任何关系。例如:
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
Student()
{
m_id = 0;
}
Student(int id) : m_id(id)
{
}
~Student()
{
}
void Display();
private:
int m_id;
};
void Student::Display()
{
cout << " id : " << m_id << endl;
}
int main()
{
Student s1;
s1.Display();
Student s2(2);
s2.Display();
return 0;
}
执行结果如下:
![](https://raw.githubusercontent.com/breakerthb/CloudIDE_WB/master/PicBed/2017/1502788375.png)
对于Student
类的两个对象,s1
和s2
,它们的m_id
是两个完全不同的变量。如果我们希望这两个对象共享同一个变量该怎么办呢?
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
Student()
{
m_id = 0;
}
Student(int id) : m_id(id)
{
}
~Student()
{
}
void Display();
private:
int m_id;
static int num;
};
int Student::num = 1;
void Student::Display()
{
cout << " id : " << m_id << endl;
cout << " num: " << num++ << endl;
}
int main()
{
Student s1;
s1.Display();
Student s2(2);
s2.Display();
return 0;
}
执行结果如下:
![](https://raw.githubusercontent.com/breakerthb/CloudIDE_WB/master/PicBed/2017/1502787903.png)
这段代码中,被static
修饰的成员变量num
就成为了被所有对象共享的变量,叫做静态成员变量。
需要注意的是:
- 静态成员变量需要在类外部初始化,不能写在构造函数中。因为这个变量是属于类本身的,而不是任何一个对象的。
- 访问静态成员变量时,要使用类名 +
::
+ 变量名的形式。如:Student::num
。
3. 静态成员函数
成员函数也可以定义为静态的,静态成员函数同样属于任何一个对象。使用方法如下:
3.1 声明
在普通成员函数前加static
就成为静态成员函数。例如:
static void Display();
3.2 调用
在调用静态成员函数时,可以使用下面两种方法:
-
类名 +
::
+ 函数名Student::Display();
-
对象名 +
.
+ 函数名s.Display();
3.3 注意
- 非静态成员函数中有
this
指针,但静态成员函数中没有。 - 静态成员函数中只能使用静态成员变量,不能使用非静态成员变量。
在之前的代码中加入静态成员函数的使用,代码如下:
#include <iostream>
#include <string>
using namespace std;
class Student
{
public:
Student()
{
m_id = 0;
}
Student(int id) : m_id(id)
{
}
~Student()
{
}
void Display();
static void Show();
private:
int m_id;
static int num;
};
int Student::num = 1;
void Student::Display()
{
cout << " id : " << m_id << endl;
cout << " num: " << num++ << endl;
}
void Student::Show()
{
cout << "Show()" << endl;
cout << " num: " << num << endl;
}
int main()
{
Student s1;
s1.Display();
Student s2(2);
s2.Display();
Student::Show();
return 0;
}
执行结果如下:
![](https://raw.githubusercontent.com/breakerthb/CloudIDE_WB/master/PicBed/2017/1502845618.png)
我是天花板,让我们一起在软件开发中自我迭代。
如有任何问题,欢迎与我联系。