C 學習筆記34 類的static成員

2021-07-08 20:02:05 字數 3020 閱讀 7270

靜態成員:不是任意物件的組成部分,但由給定類的全體物件所共享的資料成員或函式成員。

靜態成員是與類關聯的物件,而不是像普通的成員那樣與類的物件相關聯。

靜態成員可以是資料成員,或成員函式。

靜態成員遵循正常的共有/私有訪問規則。

通過關鍵字static宣告靜態成員。

靜態資料成員必須在類定義體的外部定義,且只能定義一次。靜態資料成員不能通過類的建構函式初始化,而是應該在定義時進行初始化。

保證物件正好定義一次的方法是,將static資料成員的定義放在包含類的非內聯成員函式定義的原始檔中。

如下所示:

// test.h

// 定義類

class box

box(double new_len, double new_width) :len(new_len), width(new_width) {}

double volume()

private:

double len;

double width;

static double height;

};// 定義、初始化類的靜態資料成員

double box::height = 10;

//在main()函式中使用該類

int main()

輸出為120,即1*2*10.

我們在類的定義體外將靜態成員height初始化為10.

注意:不要將靜態成員的定義放在標頭檔案中,除非你能保證該標頭檔案不會被兩個不同的原始檔包含,不然會報重複定義錯誤,相當於是在兩個原始檔中都定義了同乙個變數。對於這種同一標頭檔案被不同原始檔包含的情況,使用#ifndef或者#pragma once是沒用的。這種預編譯巨集是為了解決乙個原始檔兩次包含同乙個標頭檔案的問題。

同時,對靜態資料成員的定義也不能放在main()函式裡,否則編譯報錯:error c2655: 「box::height」: 當前範圍內的定義或重新宣告非法。

正確的做法,就如上面所說,把它放在定義類的成員函式的原始檔中。

const static資料成員的值一經定義不能修改。

特別地,當該const static成員是整型時,可以在類的定義體內初始化,但是仍然必須在類的定義體外定義,此時定義時可以不必,也不能再賦值了。如果在類的定義體內和該const static整型成員的定義處都賦值,會報重複初始化錯誤,哪怕賦的是相同的值。

注意,這種在類的定義體內初始化的寫法,只適用於整型!

如下所示:

// test.h

class box

box(double new_len, double new_width) :len(new_len), width(new_width) {}

double volume()

static box box; //該類型別的靜態資料成員

private:

double len;

double width;

static double height;

//static const double weight = 50.0; //必須是整型?!!error c2864: 帶有類內初始值設定項的靜態資料成員必須具有不可變的常量整型

static const double weight;//不在類內給定初始值的static const則不要求必須是整型。好奇葩!!

static const int inr = 10;

//const static double weight; //const 與static誰前誰後都可以

};// test.c

double box::height = 10;

const int box::inr;

const double box::weight = 50.3;

box box::box(3, 4);

int main()

為什麼整型會有特殊待遇,感覺很奇葩。

另外請注意,靜態資料成員可以是本類型別的,而一般的成員最多是本類型別的指標或引用。

上面的例子中幾個cout的輸出是相同的,都是120,  3*4*10

在宣告成員函式時,在前面加static即成為靜態成員函式。

注意,只能在宣告的時候加,在體外定義的時候,不能再加static限定,否則報錯:

error c2724: 「bar::callsfooval」:「static」不應在檔案範圍內定義的成員函式上使用

靜態成員函式與普通成員函式最大的區別是,其沒有this指標,所以它不能直接使用類的非靜態資料成員,但可以直接使用類的靜態資料成員。如果一定要使用類的非靜態資料成員,就一定要指明物件(估計該物件也只能是全域性變數了)。但一般而言還是盡量不要這麼使用。

由於static成員不是任何物件的組成部分,沒有this指標,不可能修改函式所屬的物件,所以其也不能被限定為const。

// test.h

class foo

foo(int new_val) :ival(new_val) {}

int get_value()

private:

int ival;

};class bar

// 普通的成員函式,也能使用靜態資料成員

static int callsfooval() //使用了靜態資料成員

private:

static int itimes;

static int i;

static foo fool;

};// test.c

foo bar::fool(3132);

int bar::i = 520;

int bar::itimes = 0;

//int bar::itimes; //ok,自動賦0值

int main()

最終輸出:

5203132  3132 2

注意,靜態成員函式只能使用靜態資料成員;但是普通的成員函式,既能使用普通的資料成員,也能使用靜態資料成員。

C 學習筆記(3,4章)

第三章 3.1 變數 符號常量 預處理器方式 在c 編譯過程中,首先將源 傳遞給預處理器。在這裡 define和 include一樣,也是乙個預處理器編譯指令。該編譯指令告訴預處理器,在程式中查詢inf,並將程式中所有的inf替換成為1e9。完成這項操作之後再替換。3.2 const const的好...

C 筆記(五) static類成員

在設計乙個類的時候,我們希望某些屬性是所有物件共用的,而不是不同物件有不同地屬性。那我們可以使用static關鍵字進行宣告,使這個類成員變成靜態成員。例如 存在銀行裡的錢,都有相同的利息,不會因為賬戶的不同而利息不同。我們在生成銀行賬戶這個物件時,此時就希望它的利息這個成員是共用的。static關鍵...

C 學習筆記 3 4多繼承

多繼承概念 1.乙個類有多個直接基類的繼承關係稱為多繼承 2.多繼承宣告語法 class 派生類名 訪問控制 基類名1,訪問控制 基類名2,訪問控制 基類名n void printb1 private int b1 class base2 void printb2 private int b2 cl...