C++ class中的靜態(static)成員

C++ class中的靜態(static)成員

(1)?????? 靜態數據成員

? ?①一般地靜態數據成員在該類定義之外被初始化,如同一個成員函數被定義在類定義之外一樣。在這種定義中的靜態成員的名字必須被其類名限定修飾,例如下面是_interestRate的初始化

// 靜態類成員的顯式初始化

#include "account.h"

double Account::_interestRate = 0.0589;

?

? ?②靜態數據成員的初始化不應該被放在頭文件中,而應該放在含有類的非inline 函數定義的文件中。靜態數據成員可以被聲明為任意類型。例如:

?

#include <string>

class Account

{

// ...

private:

??? static const string name;

};

const string Account::name( "Savings Account" );

?

作為特例,整型的const 靜態數據成員可以在類體中用一常量值初始化。例如,如果決定用一個字符數組而不是string 來存儲賬戶的姓名那么我們可以用int 型的const 數據成員指定該數組的長度,例如:

?

// 頭文件

class Account {

// ...

private:

static const int nameSize = 16;

static const char name[nameSize];

};

// 文本文件

const int Account::nameSize; // 必需的成員定義

const char Account::name[nameSize] = "Savings Account";

?

用常量值作初始化整型的const 靜態數據成員是一個常量表達式(constant expression)。如果需要在類體中使用這個被命名的值,那么,類設計者可聲明這樣的靜態數據成員。例如,因為const 靜態數據成員nameSize是一個常量表達式,所以類的設計者可以用它來指定數組數據成員name 的長度。在類體內初始化一個const 靜態數據成員時,該成員必須仍然要被定義在類定義之外。但是因為這個靜態數據成員的初始值是在類體中指定的所以在類定義之外的定義不能指定初始值。

因為name 是一個數組,不是整型,所以它不能在類體內被初始化。任何試圖這么做的行為都會導致編譯時刻錯誤,例如:

?

class Account {

// ...

private:

static const int nameSize = 16; // ok: 整型

static const char name[nameSize] =

"Savings Account"; // 錯誤

};

name 必須在類定義之外被初始化。

這個例子還說明了一點我們注意到成員nameSize 指定了數組name 的長度,而數組name的定義出現在類定義之外

const char Account::name[nameSize] = "Savings Account";

nameSize 沒有被類名Account 限定修飾。盡管nameSize 是私有成員,但是name的定義仍沒有錯。如同類成員函數的定義可以引用類的私有成員一樣,靜態數據成員的定義也可以。靜態數據成員name的定義是在它的類的域內,當限定修飾名Account::name被看到之后,它就可以引用Account 的私有數據。

?

③靜態數據成員的訪問

1.???? 在類的成員函數中可以直接訪問該類的靜態數據成員,而不必使用成員訪問操作符:

inline double Account::dailyReturn()

{

??? return( _interestRate / 365 * _amount );

}

2.???? 在非成員函數中,我們必須以如下兩種方式訪問靜態數據成員:

?? I. 使用成員訪問操作符

class Account {

// ...

private:

friend int compareRevenue( Account& , Account* );

// 余下部分未變

};

// 引用和指針參數來說明對象和指針訪問

int compareRevenue( Account &ac1, Account *ac2 )

{

double ret1, ret2;

ret1 = ac1._interestRate * ac1._amount;

ret2 = ac2->_interestRate * ac2->_amount;

// ...

}

ac1._interestRate 和ac2->_interestRate都引用靜態成員Account::_interestRate

????

????? II. 訪問靜態數據成員的另一種方法,是用被類名限定修飾的名字直接訪問它

// 用限定修飾名訪問靜態成員

if ( Account:_interestRate < 0.05 )

當我們不通過類的成員訪問操作符訪問靜態數據成員時必須指定類名以及緊跟其后的域操作符????????Account:: 。

因為靜態成員不是全局對象所以我們不能在全局域中找到它下面的friend 函數compareRevenue()的定義與剛剛給出的等價

?

int compareRevenue( Account &ac1, Account *ac2 )

{

double ret1, ret2;

ret1 = Account::_interestRate * ac1._amount;?? //因為是friend函數,才可以訪

//私有的靜態成員變量_interestRate

ret2 = Account::_interestRate * ac2->_amount;

// ...

}

注意:靜態數據成員的“惟一性”本質(獨立于類的任何對象而存在的惟一實例),使它能夠以獨特的方式被使用,這些方式對于非static 數據成員來說是非法的

①靜態數據成員的類型可以是其所屬類,而非static 數據成員只能被聲明為該類的對象的指針或引用。例如:

class Bar {

public:

// ...

private:

static Bar mem1; // ok

Bar *mem2; // ok

Bar mem3; // 錯誤

};

2 靜態數據成員可以被作為類成員函數的缺省實參,而非static 成員不能。例如:

extern int var;

class Foo {

private:

int var;

static int stcvar;

public:

// 錯誤: 被解析為非 static 的 Foo::var

// 沒有相關的類對象

int mem1( int = var );

?

// ok: 解析為 static 的 Foo::stcvar

// 無需相關的類對象

int mem2( int = stcvar );

?

// ok: int var 的全局實例

int mem3( int = ::var );

};

?

(2)?????? 靜態成員函數

??? 使用類的靜態成員函數來訪問類的私有靜態數據成員。

??? 靜態成員函數的聲明除了在類體中的函數聲明前加上關鍵字static, 以及不能聲明為const 或volatile之外,與非靜態成員函數相同。出現在類體外的函數定義不能指定關鍵字static。

靜態成員函數沒有this 指針,因此在靜態成員函數中,隱式或顯式地引用這個指針都將導致編譯時刻錯誤。試圖訪問隱式引用this 指針的非靜態數據成員也會導致編譯時刻錯誤。例如前面給出的成員函數dailyReturn()就不能被聲明為靜態成員函數,因為它訪問了非靜態數據成員amount。

我們可以用成員訪問操作符點. 和箭頭-> 為一個類對象或指向類對象的指針調用靜態成員函數,也可以用限定修飾名直接訪問或調用靜態成員函數,而無需聲明類對象。

?

(3)在派生類中的靜態數據成員與靜態成員函數

class的static data member只有一份實例,被class和class的派生類的所有實例共享。class和class的派生類共用同一塊內存中的靜態數據成員。

一個簡單的例子:

#include <iostream>

using namespace std;

?

class A{

public:

???? A(){}

???? ~A(){}

???? static void SetA(int b){a=b;}

???? static int GetA(){return a;}

private:

???? static int a;

};

int A::a = 5;

class B : public A{

public:

???? B(){}

???? ~B(){}

};

int main(){

cout<< "a=" << A::GetA() <<'/n';? //輸出5

cout<< "a=" << B::GetA() <<'/n'; ?//輸出5

B::SetA(4);

cout<< "a=" << B::GetA() <<'/n';? //輸出4??

cout<< "a=" << A::GetA() <<'/n';? //輸出4

return 0;

}??

類的靜態函數與函數中的靜態數據成員在編譯期綁定!


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452396.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452396.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452396.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用計算機彈可惜不是你,可惜不是你 還是幸虧不是你

一、 你沒有再挽留 我也沒有再回頭 就這樣 無風無雨也無晴 無疾而終二、 是我孤陋寡聞不知你心有人三、 如果作業有葬禮,全體學生定當盛裝出席.四、 縱使我有千般好 你也看不到 因為你沒有一雙愛我的眼睛五、 原來暫時共你沒緣分 來年先會變得更合襯六、 真的別回頭 你有未來 你…

PHP 完整實戰23種設計模式

PHP實戰創建型模式 單例模式 工廠模式 抽象工廠模式 原型模式 建造者模式 PHP實戰結構型模式 橋接模式 享元模式 外觀模式 適配器模式 裝飾器模式 組合模式 代理模式 過濾器模式 PHP實戰行為型模式 模板模式 策略模式 狀態模式 觀察者模式 責任鏈模式 訪問者模…

Diango博客--16.穩定易用的 Django 分頁庫,完善分頁功能(二)

文章目錄0.思路引導1.分頁效果概述2.分頁思路3.Django 第三方拓展&#xff1a;django-pure-pagination4.自定義模板0.思路引導 1&#xff09;在前面我們通過 Django Pagination 實現簡單分頁 中&#xff0c;我們實現了一個簡單的分頁導航。但效果有點差強人意&#xff0c;我們…

回歸測試

在集成測試過程中&#xff0c;每當一個新模塊結合進來時&#xff0c;程序就發生了變化&#xff1a;建立了新的數據流路徑&#xff0c;可能出現了新的I/O操作&#xff0c;激活了新的控制邏輯。在集成測試的范疇中&#xff0c;回歸測試是指重新執行已經做過的測試的某個子集&…

不同的寫法 其中 1 2 (試了下 沒有效果 ,先記載這里把)

轉載于:https://www.cnblogs.com/kaibindirver/p/9145455.html

美國西北大學 計算機工程專業排名,[轉載]美國西北大學計算機工程研究生最新專業排名...

對于打算去美國西北大學讀研究生的學生來講&#xff0c;美國西北大學研究生申請要求及美國西北大學研究生專業介紹是學生最關心的問題。本文香港介紹美國西北大學研究生申請要求及美國西北大學研究生的專業介紹&#xff0c;幫助更多的學生更好的了解美國西北大學。2016年西北大…

析構函數virtual與非virtual區別

作為通常的原則&#xff0c;如果一個類定義了虛函數&#xff0c;那么它的析構函數就應當是virtual的。因為定義了虛函數則隱含著&#xff1a;這個類會被繼承&#xff0c;并且會通過基類的指針指向子類對象&#xff0c;從而得到多態性。 這個類可能會被繼承&#xff0c;并且會…

Python:字典列表字符串方法測試

測試的一些Python中的關于字典、列表、字符串的使用方法&#xff0c;放在這里備查。整個測試代碼和說明如下&#xff1a; # -*- coding: utf-8 -*- """Python:函數中全是指針傳遞&#xff0c;而任何變量都是給予一個指針指向一個內存空間"""impo…

什么是確認測試

確認測試也稱為驗收測試&#xff0c;它的目標是驗證軟件的有效性。 通常&#xff0c;驗證指的是保證軟件正確地實現了某個特定要求的一系列活動&#xff1b;確認指的是為了保證軟件確實滿足了用戶需求而進行的一系列活動。 軟件有效性的一個簡單定義是&#xff1a;如果軟件的功…

Diango博客--17.統計各個分類和標簽下的文章數

文章目錄0.思路引導1.Model 回顧2.數據庫數據聚合3.使用 Annotate4.在模板中引用新增的屬性0.思路引導 在我們的博客側邊欄有分類列表和標簽列表&#xff0c;顯示博客已有的全部文章分類。現在想在分類名和標簽名后顯示該分類或者標簽下有多少篇文章&#xff0c;該怎么做呢&am…

HTTP協議中request報文請求方法和狀態響應碼

一個HTTP請求報文由4部分組成&#xff1a; 請求行&#xff08;request line&#xff09;請求頭部&#xff08;header&#xff09;空行請求數據下圖給出了請求報文的一般格式&#xff1a; 請求行中包括了請求方法&#xff0c;常見的請求方法有&#xff1a; GET&#xff1a;從服務…

計算機無法安裝64位操作系統,為什么我的win7旗艦版service Pack 1 64位操作系統 無法安裝(KB2670838) 這個更新...

您好&#xff01;我了解到您遇到關于這邊的問題請問無法安裝是否出現了什么錯誤代碼提示呢&#xff1f;請參考以下的步驟解決按WindowsR打開cmd里使用下面的命令關閉相關的一些服務&#xff1a;net stop wuauservnet stop cryptSvcnet stop bitsnet stop msiserver完成后&#…

bmon:一個強大的網絡帶寬監視和調試工具

bmon 是類 Unix 系統中一個基于文本&#xff0c;簡單但非常強大的 網絡監視和調試工具&#xff0c;它能抓取網絡相關統計信息并把它們以用戶友好的格式展現出來。它是一個可靠高效的帶寬監視和網速估測工具。 它能使用各種輸入模塊讀取輸入&#xff0c;并以各種輸出模式顯示輸出…

函數的調用規則(__cdecl,__stdcall,__fastcall,__pascal)

關于函數的調用規則&#xff08;調用約定&#xff09;&#xff0c;大多數時候是不需要了解的&#xff0c;但是如果需要跨語言的編程&#xff0c;比如VC寫的dll要delphi調用&#xff0c;則需要了解。 microsoft的vc默認的是__cdecl方式&#xff0c;而windows API則是__stdcall&a…

Linux 下的/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin區別

1、/bin 是所有用戶都可以訪問并執行的可執行程序。包括超級用戶及一般用戶。 供所有用戶&#xff08;包括root用戶和一般用戶&#xff09;使用的基本命令&#xff0c;主要有cat,chmod,date,cp,bash等等常用的命令。 2、/usr/bin&#xff1a;系統預裝的可執行程序&#xff0c;…

alpha測試和betal測試

如果一個軟件是為許多客戶開發的&#xff08;例如&#xff0c;向大眾公開出售的盒裝軟件產品&#xff09;&#xff0c;那么絕大多數軟件開發商都使用被稱為Alpha測試和Beta測試的過程&#xff0c;來發現那些看起來只有最終用戶才能發現的錯誤。 Alpha測試由用戶在開發者的場所進…

計算機d盤無法格式化,四種方法解決D盤無法格式化問題

不少朋友系統出現故障&#xff0c;幾乎都是選擇重裝系統的方法來解決問題。系統重裝后&#xff0c;不少朋友覺得D盤沒有什么重要的東西&#xff0c;就想將其格式化&#xff0c;可是系統出現windows無法格式該驅動器的提示&#xff0c;這是怎么回事呢&#xff1f;D盤無法格式化要…

sqlserver視圖

作用 ①簡化了操作&#xff0c;把經常使用的數據定義為視圖。 ②安全性&#xff0c;用戶只能查詢和修改能看到的數據。 ③邏輯上的獨立性&#xff0c;屏蔽了真實表的結構帶來的影響。 對視圖的修改&#xff1a;單表視圖一般用于查詢和修改&#xff0c;會改變基本表的數據&#…

非root用戶sudo_ssh免密鑰

非root用戶sudo_ssh免密鑰 目標&#xff1a;從服務器上ssh登陸后sudo免密鑰執行相應的命令 環境介紹&#xff1a; 192.168.65.128 my1-222 192.168.65.129 my2-223 192.168.65.130 web224# 步驟一&#xff1a; # 每個節點執行(不是必須&#xff0c;但是建議這樣做) cat …

復旦大學和吉大計算機考研選哪個,2016復旦大學VS吉林大學 基于排名角度的比較?...

復旦大學好還是吉林大學好首先&#xff0c;2016復旦大學好還是吉林大學好是近日問得較多的問題之一&#xff0c;小伙伴們有的從吉林大學和復旦大學的地理位置優勢角度進行分析&#xff0c;有的從吉林大學和復旦大學的強勢專業角度進行PK&#xff0c;有的甚至從吉林大學和復旦大…