程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 關於C++中的static症結字的總結

關於C++中的static症結字的總結

編輯:關於C++

關於C++中的static症結字的總結。本站提示廣大學習愛好者:(關於C++中的static症結字的總結)文章只能為提供參考,不一定能成為您想要的結果。以下是關於C++中的static症結字的總結正文


1.面向進程設計中的static
1.1靜態全局變量
在全局變量前,加上症結字static,該變量就被界說成為一個靜態全局變量。我們先舉一個靜態全局變量的例子,以下:

//Example 1
#include <iostream.h>
void fn();
static int n; //界說靜態全局變量
void main()
{
   n=20;
   cout<<n<<endl;
   fn();
}

void fn()
{
   n++;
   cout<<n<<endl;
}

靜態全局變量有以下特色:
• 該變量在全局數據辨別配內存;
• 未經初始化的靜態全局變量會被法式主動初始化為0(主動變量的值是隨機的,除非它被顯式初始化);
• 靜態全局變量在聲明它的全部文件都是可見的,而在文件以外是弗成見的; 

靜態變量都在全局數據辨別配內存,包含前面將要提到的靜態部分變量。 

普通法式的由new發生的靜態數據寄存在堆區,函數外部的主動變量寄存在棧區。主動變量普通會跟著函數的加入而釋放空間,靜態數據(即便是函數外部的靜態部分變量)也寄存在全局數據區。全局數據區的數據其實不會由於函數的加入而釋放空間。仔細的讀者能夠會發明,Example 1中的代碼中將 “static int n; //界說靜態全局變量”改成“int n; //界說全局變量”。法式照樣正常運轉。切實其實,界說全局變量便可以完成變量在文件中的同享,但界說靜態全局變量還有以下利益:
• 靜態全局變量不克不及被其它文件所用;
• 其它文件中可以界說雷同名字的變量,不會產生抵觸;

您可以將上述示例代碼改成以下:

//Example 2
//File1
#include <iostream.h>
void fn();
static int n; //界說靜態全局變量
void main()
{
   n=20;
   cout<<n<<endl;
   fn();
}

//File2
#include <iostream.h>
extern int n;
void fn()
{
   n++;
   cout<<n<<endl;
}

編譯並運轉Example 2,您就會發明上述代碼可以分離經由過程編譯,但運轉時湧現毛病。試著將 “static int n; //界說靜態全局變量”改成 “int n; //界說全局變量”
再次編譯運轉法式,仔細領會“全局變量”和"靜態全局變量"的差別。

1.2.靜態部分變量
在部分變量前,加上症結字static,該變量就被界說成為一個靜態部分變量。 我們先舉一個靜態部分變量的例子,以下:

//Example 3
#include <iostream.h>
void fn();
void main()
{
   fn();
   fn();
   fn();
}
void fn()
{
   static n=10;
   cout<<n<<endl;
   n++;
}

平日,在函數體內界說了一個變量,每當法式運轉到該語句時都邑給該部分變量分派棧內存。但跟著法式加入函數體,體系就會發出棧內存,部分變量也響應掉效。但有時刻我們須要在兩次挪用之間對變量的值停止保留。平日的設法主意是界說一個全局變量來完成。但如許一來,變量曾經不再屬於函數自己了,不再僅受函數的掌握,給法式的保護帶來未便。

靜態部分變量正好可以處理這個成績。靜態部分變量保留在全局數據區,而不是保留在棧中,每次的值堅持到下一次挪用,直到下次賦新值。

靜態部分變量有以下特色:
• 該變量在全局數據辨別配內存;
• 靜態部分變量在法式履行到該對象的聲明處時被初次初始化,即今後的函數挪用不再停止初始化;
• 靜態部分變量普通在聲明處初始化,假如沒有顯式初始化,會被法式主動初始化為0;
• 它一直駐留在全局數據區,直到法式運轉停止。但其感化域為部分感化域,當界說它的函數或語句塊停止時,其感化域隨之停止;

1.3靜態函數
在函數的前往類型前加上static症結字,函數即被界說為靜態函數。靜態函數與通俗函數分歧,它只能在聲明它的文件傍邊可見,不克不及被其它文件應用。

靜態函數的例子:

//Example 4
#include <iostream.h>
static void fn();//聲明靜態函數
void main()
{
   fn();
}
void fn()//界說靜態函數
{
   int n=10;
   cout<<n<<endl;
}

界說靜態函數的利益:
• 靜態函數不克不及被其它文件所用;
• 其它文件中可以界說雷同名字的函數,不會產生抵觸;

2、面向對象的static症結字(類中的static症結字)
2.1靜態數據成員
在類內數據成員的聲明前加上症結字static,該數據成員就是類內的靜態數據成員。先舉一個靜態數據成員的例子。

//Example 5
#include <iostream.h>
class Myclass
{
public:
   Myclass(int a,int b,int c);
   void GetSum();
private:
   int a,b,c;
   static int Sum;//聲明靜態數據成員
};
int Myclass::Sum=0;//界說並初始化靜態數據成員

Myclass::Myclass(int a,int b,int c)
{
   this->a=a;
   this->b=b;
   this->c=c;
   Sum+=a+b+c;
}

void Myclass::GetSum()
{
   cout<<"Sum="<<Sum<<endl;
}

void main()
{
   Myclass M(1,2,3);
   M.GetSum();
   Myclass N(4,5,6);
   N.GetSum();
   M.GetSum();

}

可以看出,靜態數據成員有以下特色:
• 關於非靜態數據成員,每一個類對象都有本身的拷貝。而靜態數據成員被看成是類的成員。不管這個類的對象被界說了若干個,靜態數據成員在法式中也只要一份拷貝,由該類型的一切對象同享拜訪。也就是說,靜態數據成員是該類的一切對象所共有的。對該類的多個對象來講,靜態數據成員只分派一次內存,供一切對象共用。所以,靜態數據成員的值對每一個對象都是一樣的,它的值可以更新;

• 靜態數據成員存儲在全局數據區。靜態數據成員界說時要分派空間,所以不克不及在類聲明中界說。在Example 5中,語句int Myclass::Sum=0;是界說靜態數據成員;

• 靜態數據成員和通俗數據成員一樣服從public,protected,private拜訪規矩;

• 由於靜態數據成員在全局數據辨別配內存,屬於本類的一切對象同享,所以,它不屬於特定的類對象,在沒有發生類對象時其感化域便可見,即在沒有發生類的實例時,我們便可以操作它;

• 靜態數據成員初始化與普通數據成員初始化分歧。靜態數據成員初始化的格局為:
<數據類型><類名>::<靜態數據成員名>=<值>

• 類的靜態數據成員有兩種拜訪情勢:
<類對象名>.<靜態數據成員名> 或 <類類型名>::<靜態數據成員名>
假如靜態數據成員的拜訪權限許可的話(即public的成員),可在法式中,按上述格局來援用靜態數據成員 ;

• 靜態數據成員重要用在各個對象都有雷同的某項屬性的時刻。好比關於一個存款類,每一個實例的利錢都是雷同的。所以,應當把利錢設為存款類的靜態數據成員。這有兩個利益,第一,不論界說若干個存款類對象,利錢數據成員都同享分派在全局數據區的內存,所以節儉存儲空間。第二,一旦利錢須要轉變時,只需轉變一次,則一切存款類對象的利錢全轉變過去了;

• 同全局變量比擬,應用靜態數據成員有兩個優勢:
1. 靜態數據成員沒有進入法式的全局名字空間,是以不存在與法式中其它全局名字抵觸的能夠性;
2. 可以完成信息隱蔽。靜態數據成員可所以private成員,而全局變量不克不及;

2.2靜態成員函數
與靜態數據成員一樣,我們也能夠創立一個靜態成員函數,它為類的全體辦事而不是為某一個類的詳細對象辦事。靜態成員函數與靜態數據成員一樣,都是類的外部完成,屬於類界說的一部門。通俗的成員函數普通都隱含了一個this指針,this指針指向類的對象自己,由於通俗成員函數老是詳細的屬於某個類的詳細對象的。平日情形下,this是缺省的。如函數fn()現實上是this->fn()。然則與通俗函數比擬,靜態成員函數因為不是與任何的對象相接洽,是以它不具有this指針。從這個意義上講,它沒法拜訪屬於類對象的非靜態數據成員,也沒法拜訪非靜態成員函數,它只能挪用其他的靜態成員函數。上面舉個靜態成員函數的例子。

//Example 6
#include <iostream.h>
class Myclass
{
public:
   Myclass(int a,int b,int c);
   static void GetSum();/聲明靜態成員函數
private:
   int a,b,c;
   static int Sum;//聲明靜態數據成員
};
int Myclass::Sum=0;//界說並初始化靜態數據成員

Myclass::Myclass(int a,int b,int c)
{
   this->a=a;
   this->b=b;
   this->c=c;
   Sum+=a+b+c; //非靜態成員函數可以拜訪靜態數據成員
}

void Myclass::GetSum() //靜態成員函數的完成
{
  // cout<<a<<endl; //毛病代碼,a長短靜態數據成員
   cout<<"Sum="<<Sum<<endl;
}

void main()
{
   Myclass M(1,2,3);
   M.GetSum();
   Myclass N(4,5,6);
   N.GetSum();
   Myclass::GetSum();
}

關於靜態成員函數,可以總結為以下幾點:
• 湧現在類體外的函數界說不克不及指定症結字static;
• 靜態成員之間可以互相拜訪,包含靜態成員函數拜訪靜態數據成員和拜訪靜態成員函數;
• 非靜態成員函數可以隨意率性地拜訪靜態成員函數和靜態數據成員;
• 靜態成員函數不克不及拜訪非靜態成員函數和非靜態數據成員;
• 因為沒有this指針的額定開支,是以靜態成員函數與類的全局函數比擬速度上會有少量的增加;
• 挪用靜態成員函數,可以用成員拜訪操作符(.)和(->)為一個類的對象或指向類對象的指針挪用靜態成員函數,也能夠直接應用以下格局:
<類名>::<靜態成員函數名>(<參數表>)
挪用類的靜態成員函數。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved