
static這個(gè)關(guān)鍵字我們?cè)贑語(yǔ)言的學(xué)習(xí)中已經(jīng)遇到過(guò)了。在C++中,它又被賦予了一些新的功能。
1. static在C語(yǔ)言中的用法
1.1 修飾全局變量
C語(yǔ)言的所有源文件的內(nèi)容在編譯時(shí)會(huì)被組織成一個(gè)邏輯文件進(jìn)行編譯的。這就會(huì)使一個(gè)文件的全局變量可以被程序的任意位置訪問(wèn)到。例如:
- 文件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;
}
這三個(gè)文件編譯時(shí)會(huì)報(bào)錯(cuò),因?yàn)榫幾g器認(rèn)為定義了兩個(gè)全局變量a。
首先,這種定義兩個(gè)同名變量的方法是不可取的,它會(huì)嚴(yán)重影響代碼的可讀性。如果由于某些特殊原因一定要這樣設(shè)計(jì)的話,可以修改文件file1.c如下:
#include "file1.h"
static int a = 0;
void function()
{
printf("a = %d", a);
}
這樣就能夠正確編譯了。因?yàn)榧恿?code>static修飾的變量a只在文件file1.c中起作用。
1.2 修飾函數(shù)
和1.1相似,如果我們把function函數(shù)定義改為:
static void function()
{
printf("a = %d", a);
}
這樣,在文件main.c中就無(wú)法調(diào)用這個(gè)函數(shù)了。大家可以自己驗(yàn)證一下。
1.3 修飾局部變量
我們來(lái)看看這段程序:
#include <stdio.h>
void function()
{
int a = 0;
printf("a = %d\n", a++);
}
int main()
{
function();
function();
function();
return 0;
}
執(zhí)行結(jié)果如下:
這個(gè)大家一定都能看懂,但如果改成這樣呢?
#include <stdio.h>
void function()
{
static int a = 0;
printf("a = %d\n", a++);
}
int main()
{
function();
function();
function();
return 0;
}
執(zhí)行結(jié)果是這樣的:
由于變量a被定義為static的,因此每次調(diào)用之后它的值會(huì)被記錄下來(lái),生命周期并沒(méi)有結(jié)束。
接下來(lái)我們來(lái)看看在C++中,static究竟新加入了那些功能。
2. 靜態(tài)成員變量
在C++的類的每個(gè)對(duì)象中,都有一組獨(dú)立的成員變量,我們可以對(duì)他們分別賦值,它們相互之間沒(méi)有任何關(guān)系。例如:
#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;
}
執(zhí)行結(jié)果如下:
對(duì)于Student類的兩個(gè)對(duì)象,s1和s2,它們的m_id是兩個(gè)完全不同的變量。如果我們希望這兩個(gè)對(duì)象共享同一個(gè)變量該怎么辦呢?
#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;
}
執(zhí)行結(jié)果如下:
這段代碼中,被static修飾的成員變量num就成為了被所有對(duì)象共享的變量,叫做靜態(tài)成員變量。
需要注意的是:
- 靜態(tài)成員變量需要在類外部初始化,不能寫(xiě)在構(gòu)造函數(shù)中。因?yàn)檫@個(gè)變量是屬于類本身的,而不是任何一個(gè)對(duì)象的。
- 訪問(wèn)靜態(tài)成員變量時(shí),要使用類名 +
::+ 變量名的形式。如:Student::num。
3. 靜態(tài)成員函數(shù)
成員函數(shù)也可以定義為靜態(tài)的,靜態(tài)成員函數(shù)同樣屬于任何一個(gè)對(duì)象。使用方法如下:
3.1 聲明
在普通成員函數(shù)前加static就成為靜態(tài)成員函數(shù)。例如:
static void Display();
3.2 調(diào)用
在調(diào)用靜態(tài)成員函數(shù)時(shí),可以使用下面兩種方法:
-
類名 +
::+ 函數(shù)名Student::Display();
-
對(duì)象名 +
.+ 函數(shù)名s.Display();
3.3 注意
- 非靜態(tài)成員函數(shù)中有
this指針,但靜態(tài)成員函數(shù)中沒(méi)有。 - 靜態(tài)成員函數(shù)中只能使用靜態(tài)成員變量,不能使用非靜態(tài)成員變量。
在之前的代碼中加入靜態(tài)成員函數(shù)的使用,代碼如下:
#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;
}
執(zhí)行結(jié)果如下:
我是天花板,讓我們一起在軟件開(kāi)發(fā)中自我迭代。
如有任何問(wèn)題,歡迎與我聯(lián)系。