第6篇:C++ 靜態(tài)成員和函數(shù)

在前面1-5篇中詳細(xì)講解一些類的示例卷仑,其中每個對象都有自己的數(shù)據(jù)成員數(shù)據(jù)集仗岸。 該類的每個成員函數(shù)都可以訪問其類的任何對象的任何成員茁瘦。在某些情況下涝焙,可能希望定義可以由該類的所有實例都能訪問的公共數(shù)據(jù)字段。在C中也遇到這種情況距潘,C源文件中的幾個函數(shù)需要訪問同一變量炼列。 C的一種常見解決方案是同個源文件中定義所有函數(shù),并且定義一個static變量.在源文件之外音比,變量名不可見俭尖。 這種方法非常有效,但是違反了我們在每個源文件中僅使用一個函數(shù)的原則。

C ++通過定義靜態(tài)成員來解決該問題:這些靜態(tài)成員是類的所有對象所共有的數(shù)據(jù)和函數(shù)稽犁,并且(在私有部分中定義時)在類外部無法訪問焰望。 這些靜態(tài)成員是本章的主題。

靜態(tài)成員不能定義為virtual函數(shù)已亥。 虛擬成員函數(shù)是普通成員熊赖,因為它具有this指針。 由于靜態(tài)成員函數(shù)沒有此指針虑椎,因此無法將其聲明為virtual秫舌。

靜態(tài)數(shù)據(jù)

類的任何數(shù)據(jù)成員都可以聲明為static; 無論是在類接口的public部分還是private部分中绣檬。 與為該類的每個對象一次又一次創(chuàng)建的非靜態(tài)數(shù)據(jù)成員相反,此類數(shù)據(jù)成員僅創(chuàng)建和初始化一次嫂粟。

程序啟動后立即創(chuàng)建靜態(tài)數(shù)據(jù)成員娇未。 即使它們是在程序執(zhí)行周期的最開始創(chuàng)建的,它們?nèi)匀皇瞧漕惖恼嬲蓡T星虹。為了方便區(qū)分靜態(tài)數(shù)據(jù)成員普通數(shù)據(jù)成員建議為靜態(tài)數(shù)據(jù)成員的名稱加上s_前綴零抬。

公共靜態(tài)數(shù)據(jù)成員是全局變量。 程序的所有代碼都可以訪問它們宽涌,只需使用其類名平夜,范圍解析運算符及其成員名即可。以下是詳細(xì)的例子:
類接口:cone.hh文件

#include  <string>
class Cone
{
   std::string d_name;
    double d_radius;
    double d_height;
    double d_busLength;

public:
    static double s_pi;
    static int s_count;
    Cone(std::string, double, double);

    //計算體積
    double volume();

    //計算底面面積
    double bottom_area();

    //計算表面積
    double surface_area();

    //計算側(cè)面積
    double side_area();

    //顯示容積
    void display_volume();
};

如果沒有其他初始化卸亮,則在創(chuàng)建第一個對象時忽妒,所有靜態(tài)數(shù)據(jù)都會根據(jù)其聲明的數(shù)據(jù)類型進(jìn)行類內(nèi)默認(rèn)值初始化

靜態(tài)數(shù)據(jù)成員的初始化:不能將其放在類接口中兼贸,一般來說,公共的靜態(tài)數(shù)據(jù)成員是放在類接口外部進(jìn)行初始化段直,方法是使用作用域運算符::來重新聲明靜態(tài)變量,以標(biāo)識它屬于哪個類溶诞,下面是一個很貼切的例子。
類實現(xiàn):cone.cpp文件

#include "../header/cone.hh"
#include <iostream>
#include <math.h>

// 靜態(tài)成員在類接口外初始化
int Cone::s_count = 0;
double Cone::s_pi = 3.14;

Cone::Cone(std::string name, double r, double h) : d_radius(r), d_height(h), d_name(name)
{

    s_count++;
    std::cout << "創(chuàng)建一個錐體,目前數(shù)量是" << s_count << std::endl;
    if (d_radius > 0 && d_height > 0)
    {
        d_busLength = sqrt(d_radius * d_radius + d_height * d_height);
    }
}
inline double Cone::volume()
{
    return s_pi * d_radius * d_radius * d_height / 1000 / 3.0;
}

inline void Cone::display_volume()
{
    std::cout << "錐體"<<d_name<<"的容積是" << volume() << "L" << std::endl;
}

double Cone::side_area()
{
    //公式PI*R*L
    return s_pi * d_radius * d_busLength;
}

inline double Cone::surface_area()
{
    return side_area() + bottom_area();
}

inline double Cone::bottom_area()
{
    //公式:PI*R*R
    return s_pi * d_radius * d_radius;
}

調(diào)用代碼:

int main(int argc, char const *argv[])
{

    Cone c1 = {"N1", 43.5, 72.5};
    Cone c2 = {"N2", 52.77, 23.33};
    Cone c3 = {"N3", 47.5, 72.5};
    Cone c4 = {"N4", 32.77, 33.33};

    c1.display_volume();
    c2.display_volume();
    c3.display_volume();
    c4.display_volume();

    return 0;
}

而實際項目中,我們更傾向于將整個項目的所有類的靜態(tài)數(shù)據(jù)成員集中在某個源文件當(dāng)中(例如:st_data.cpp),然后在程序入口的源文件include這個st_data.cpp就可以了。

由于構(gòu)造函數(shù)是為類的每個新對象調(diào)用的猫妙,因此構(gòu)造函數(shù)不會初始化靜態(tài)數(shù)據(jù)成員串绩。 最多就是修改。 原因是靜態(tài)數(shù)據(jù)成員在調(diào)用該類的任何構(gòu)造函數(shù)之前就已經(jīng)存在枉圃。 定義靜態(tài)數(shù)據(jù)成員時功茴,在任何成員函數(shù)之外都將對其進(jìn)行初始化,就像對普通(非類)全局變量的初始化一樣孽亲。

靜態(tài)成員函數(shù)

除了靜態(tài)數(shù)據(jù)成員痊土,C ++還允許我們定義靜態(tài)成員函數(shù)。與類的所有對象共享的靜態(tài)數(shù)據(jù)類似墨林,靜態(tài)成員函數(shù)的特征如下赁酝。

  1. 靜態(tài)成員函數(shù)可以訪問其類的所有靜態(tài)成員犯祠,也可以訪問其類的對象的成員(包括private或public),但前提要指定一個該類的對象.
  2. 靜態(tài)成員函數(shù)并沒與其類的任何對象關(guān)聯(lián),因此它們沒有this指針酌呆。
  3. 靜態(tài)成員函數(shù)只能從類外部訪問靜態(tài)數(shù)據(jù)成員衡载,其他靜態(tài)成員函數(shù)和任何其他函數(shù)。
  4. 靜態(tài)成員函數(shù)可以被在類接口的public部分聲明的其他靜態(tài)成員函數(shù)調(diào)用隙袁,而無需指定其類的對象痰娱。以下示例說明了靜態(tài)成員函數(shù)的這種特征:

下面的示例是為了上面的靜態(tài)成員函數(shù)的特征的,我們在前文的Cone類接口中增加兩個靜態(tài)成員函數(shù)的聲明
類接口

 class Cone{
      .....
     //顯示側(cè)面面積
    static void display_sideArea(Cone &);

    //顯示表面積
    static void display_surfArea(Cone &);
}

類實現(xiàn)
很多情況下:我們可能需要用靜態(tài)成員函數(shù)菩收,調(diào)用它所屬的類的某個實例的非靜態(tài)數(shù)據(jù)成員 梨睁, 正是特征1所說的那樣。特征2和3更不用說了娜饵,下面這些示例都是從類外調(diào)用

void Cone::display_sideArea(Cone &obj)
{
    std::cout << obj.d_name << "側(cè)面積:" << obj.side_area() << std::endl;
}

void Cone::display_surfArea(Cone &obj)
{
    std::cout << obj.d_name << "表面積:" << obj.surface_area() << std::endl;
}

下面是靜態(tài)成員函數(shù)調(diào)用同一個類的靜態(tài)函數(shù)坡贺,正如上面特征4所述

void Cone::display_all(Cone &obj)
{
    std::cout << "型號:" << obj.d_name << std::endl;
    std::cout << "參數(shù):"
              << "r " << obj.d_radius << " h " << obj.d_height << " l " << obj.d_busLength << std::endl;

    display_surfArea(obj);
    display_sideArea(obj);
}

調(diào)用代碼

#include "./cone.cpp"
#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{

    Cone c1 = {"N1", 43.5, 72.5};
    Cone c2 = {"N2", 52.77, 23.33};
    Cone c3 = {"N3", 47.5, 72.5};
    Cone c4 = {"N4", 32.77, 33.33};

    c1.display_volume();
    c2.display_volume();
    c3.display_volume();
    c4.display_volume();

    Cone::display_sideArea(c1);
    Cone::display_surfArea(c2);

    Cone::display_all(c1);
    Cone::display_all(c2);
    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市箱舞,隨后出現(xiàn)的幾起案子遍坟,更是在濱河造成了極大的恐慌,老刑警劉巖晴股,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件愿伴,死亡現(xiàn)場離奇詭異,居然都是意外死亡电湘,警方通過查閱死者的電腦和手機隔节,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寂呛,“玉大人官帘,你說我怎么就攤上這事∶烈辏” “怎么了刽虹?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長呢诬。 經(jīng)常有香客問我涌哲,道長,這世上最難降的妖魔是什么尚镰? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任阀圾,我火速辦了婚禮,結(jié)果婚禮上狗唉,老公的妹妹穿的比我還像新娘初烘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布肾筐。 她就那樣靜靜地躺著哆料,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吗铐。 梳的紋絲不亂的頭發(fā)上东亦,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機與錄音唬渗,去河邊找鬼典阵。 笑死,一個胖子當(dāng)著我的面吹牛镊逝,可吹牛的內(nèi)容都是我干的壮啊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼撑蒜,長吁一口氣:“原來是場噩夢啊……” “哼歹啼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起减江,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎捻爷,沒想到半個月后辈灼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡也榄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年巡莹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甜紫。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡降宅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出囚霸,到底是詐尸還是另有隱情腰根,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布拓型,位于F島的核電站额嘿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏劣挫。R本人自食惡果不足惜册养,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望压固。 院中可真熱鬧球拦,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至点弯,卻和暖如春扇调,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背抢肛。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工狼钮, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人捡絮。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓熬芜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親福稳。 傳聞我的和親對象是個殘疾皇子涎拉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對...
    cosWriter閱讀 11,113評論 1 32
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,523評論 1 51
  • 整理來自互聯(lián)網(wǎng) 1,JDK:Java Development Kit的圆,java的開發(fā)和運行環(huán)境鼓拧,java的開發(fā)工具...
    Ncompass閱讀 1,540評論 0 6
  • 一:java概述: 1,JDK:Java Development Kit越妈,java的開發(fā)和運行環(huán)境季俩,java的開發(fā)...
    慕容小偉閱讀 1,796評論 0 10
  • C++文件 例:從文件income. in中讀入收入直到文件結(jié)束,并將收入和稅金輸出到文件tax. out梅掠。 檢查...
    SeanC52111閱讀 2,799評論 0 3