2008年8月14日 星期四

c++ - static

這裡對static關鍵字說明一下,
當類別中的資料成員使用static時,類別的所有物件都共用記憶體位置。

另一方面當函數宣告成static時,方法將成為類別的方法。
可以不用建立物件,直接透過類別呼叫static function,用以下的方法
類別::function(int x,int y)

而且,值得注意的是,當在一個副程式中定義一個static變數時,當副程式執行完時,此變數仍占用憶體位置,而且,因為,它是區域變數,所以,其它位置沒有辦法使用這一個變數。

[2008.10.23補充]
當要宣告一個全域的static變數時,需要在類別定義之外初始化靜態變數,如果不是這樣,編譯器會警告沒有為該變數分配記憶體。

#include <string>

class bird_class{
public:
  static int number_seen;
  string name;
  void increment_count() {number_seen++;}
  bird_class(string text);
};

int bird_class::number_seen=0;

bird_class::bird_class(string text)
{
  name = text;
  number_seen = 0;
}


[2008.11.28補充]
由於靜態成員是屬於類別而不是物件,所以當您呼叫靜態函式時,並不會傳入物件的位址,所以靜態函式中不會有this指標,由於沒有this指標,所以在C ++的靜態函式中不允許使用非靜態成員,因為沒有this來儲存物件的位址,也就無法辨別要存取的是哪一個物件的成員,事實上,如果您在靜態函式中使用非靜態資料成員,在編譯時就會出現以下的錯誤訊息:
  invalid use of member `Ball::_radius' in static member function

或者是在靜態函式中呼叫非靜態函式,在編譯時就會出現以下的錯誤訊息:
  cannot call member function `std::string& Ball::name()' without object

[2010.01.30 補充]
在C語言中,若同時在一個project中,一共有2個.c檔,其中一個是main.c而另一個是common.c,同時有一個global變數。
main.c

#include <stdio.h>
#include <stdlib.h>

int x = 2;

int main(int argc, char *argv[])
{
  printf ("value: %d\n", x);
  system("PAUSE");
  return 0;
}

common.c
int x = 1;

在編譯之後,會出現以下錯誤。
Linker會給你一個錯誤:multiple definition of `x'
由此可以推測出,在同一個project中,所有的global變數,是存放在同一個空間的,因此,才會衝突啊,但是,不是說存在同一個空間,就可以直接使用喔,詳情可以參考extern

而要如何避免以上的問題,這個時候,就要使用static關鍵字啦!而使用static會有以下的特性。
1. 假設在common.c宣告一個static的global變數,則這一個變數只有這一個.c檔案內的成員可以使用(換句話說,它不能與extern共用喔)!若是在某一個函式中宣告一個static的區域變數,則只有這一個函式內的成員才可以存取它。因此,就不會發生上述的衝突啦~如下:
main.c
#include <stdio.h>
#include <stdlib.h>

int x = 2;

int main(int argc, char *argv[])
{
  printf ("value: %d\n", x);
  system("PAUSE");
  return 0;
}

common.c
static int x = 1;

就不會發生衝突的錯誤啦!
2. 宣告的static變數,會一直保留在記憶體中,直到程式執行結束。在這裡,我們可以做一個實驗。
main.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
  printf ("value: %d\n", getvalue ());
  printf ("value: %d\n", getvalue ());
  system("PAUSE");
  return 0;
}

common.h
#ifndef _COMMON_H_
#define _COMMON_H_

int getvalue (
  );

#endif

common.c
int getvalue (
  )
{
  static int value = 1;
  value++;
  return value;
}

注意喔!
會印出來的值會是2與3喔,若不加static的話,印出來的值,就會是2與2。
由此實驗得知,可以得知道,當宣告一個staitc的變數時,會一直保存到程式執行結束,而下次再使用的時候,仍會保持上次使用之後的值。

參考資料:
static函數的用途?

沒有留言: