自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

c++ Static 成員:讓類變量不再“孤單”

開發(fā) 前端
靜態(tài)成員變量和靜態(tài)成員函數(shù)讓我們?cè)?C++ 中能更方便地管理共享數(shù)據(jù)和功能。它的一個(gè)關(guān)鍵特點(diǎn)是:它們屬于整個(gè)類,而不是某個(gè)具體的對(duì)象。

前言

如果說 static 變量讓函數(shù)“記住”上一次的狀態(tài),那么 static 成員變量就像是整個(gè)類的“共享記憶”。這次,我們將從類的角度來聊聊 static 成員變量和函數(shù),幫你徹底搞懂它們是什么,怎么用。

什么是 static 成員變量?

在 C++ 中,類的成員變量通常是屬于某個(gè)具體對(duì)象的,每個(gè)對(duì)象都會(huì)有一份獨(dú)立的成員變量。而 static 成員變量 可不一樣,它是所有對(duì)象共享的一個(gè)變量。

舉個(gè)例子:

假設(shè)我們有一個(gè)類 Car,它有一個(gè)成員變量 carCount 用來統(tǒng)計(jì)車的數(shù)量。

如果每個(gè) Car 對(duì)象都單獨(dú)存儲(chǔ)這個(gè)數(shù)量,那就沒什么意義了。因?yàn)?nbsp;carCount 應(yīng)該是所有 Car 對(duì)象共享的,而不是每個(gè)對(duì)象都自有一份。這個(gè)時(shí)候,就可以用 static 來聲明 carCount。

#include <iostream>
using namespace std;

class Car {
public:
    static int carCount;  // 聲明靜態(tài)成員變量

    Car() {
        carCount++;
    }
};

// 靜態(tài)成員變量需要在類外定義
int Car::carCount = 0;

int main() {
    Car car1;
    Car car2;

    cout << "Number of cars: " << Car::carCount << endl;  // 輸出:2
    return 0;
}

在這個(gè)例子中,carCount 變量是靜態(tài)的,所有 Car 對(duì)象共享同一個(gè) carCount,所以無論創(chuàng)建多少個(gè) Car 對(duì)象,它都會(huì)累加。

如何訪問 static 成員?

靜態(tài)成員的訪問和普通成員稍微有些不同。普通成員變量需要通過對(duì)象來訪問,而靜態(tài)成員變量可以通過 類名:: 來直接訪問,甚至不需要?jiǎng)?chuàng)建對(duì)象。

訪問靜態(tài)成員:

class Car {
public:
    static int carCount;  // 靜態(tài)成員變量

    Car() {
        carCount++;
    }
};

// 在類外定義靜態(tài)成員
int Car::carCount = 0;

int main() {
    // 直接通過類名訪問靜態(tài)成員
    cout << "Initial car count: " << Car::carCount << endl;  // 輸出:0

    Car car1;
    cout << "After one car: " << Car::carCount << endl;  // 輸出:1
    Car car2;
    cout << "After two cars: " << Car::carCount << endl;  // 輸出:2

    return 0;
}

你可以看到,靜態(tài)成員 carCount 通過 Car::carCount 來訪問,不需要?jiǎng)?chuàng)建 Car 對(duì)象。這樣就避免了不必要的內(nèi)存浪費(fèi)。

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

什么是靜態(tài)成員函數(shù)?

靜態(tài)成員函數(shù) 是屬于類的,而不是某個(gè)對(duì)象的。也就是說,你可以通過類名來調(diào)用它,而不需要先創(chuàng)建對(duì)象。這一點(diǎn)與普通的成員函數(shù)不同,普通成員函數(shù)是通過對(duì)象來調(diào)用的。

它有什么特點(diǎn)?

1、類級(jí)別的函數(shù):靜態(tài)成員函數(shù)屬于類級(jí)別,不依賴于任何對(duì)象。你不需要?jiǎng)?chuàng)建類的實(shí)例,就能通過類名直接調(diào)用。

2、只能訪問靜態(tài)成員:靜態(tài)成員函數(shù)只能訪問類中的靜態(tài)成員變量和其他靜態(tài)成員函數(shù),因?yàn)樗鼪]有綁定到任何具體的對(duì)象,也就無法訪問屬于對(duì)象的非靜態(tài)成員。

3、沒有 this 指針:普通成員函數(shù)有一個(gè)隱含的 this 指針,指向調(diào)用該函數(shù)的對(duì)象,而靜態(tài)成員函數(shù)沒有 this 指針。

與普通成員函數(shù)的區(qū)別是什么?

  • 普通成員函數(shù):普通成員函數(shù)是與對(duì)象關(guān)聯(lián)的,它可以訪問類的靜態(tài)和非靜態(tài)成員。訪問非靜態(tài)成員時(shí),它依賴于對(duì)象的 this 指針。
  • 靜態(tài)成員函數(shù):靜態(tài)成員函數(shù)沒有 this 指針,它不能直接訪問非靜態(tài)成員,只能訪問靜態(tài)成員。

舉個(gè)例子:

#include <iostream>
using namespace std;

class Car {
public:
    static int carCount;  // 靜態(tài)成員變量

    Car() {
        carCount++;
    }

    // 靜態(tài)成員函數(shù)
    static void printCarCount() {
        cout << "Number of cars: " << carCount << endl;
    }
};

// 靜態(tài)成員變量需要在類外定義
int Car::carCount = 0;

int main() {
    Car car1;
    Car car2;

    // 通過類名調(diào)用靜態(tài)成員函數(shù)
    Car::printCarCount();  // 輸出:2
    return 0;
}

在上面的代碼中,printCarCount() 是一個(gè)靜態(tài)成員函數(shù),它只能訪問靜態(tài)成員變量 carCount,不能直接訪問非靜態(tài)成員變量。如果嘗試訪問非靜態(tài)成員,編譯器會(huì)報(bào)錯(cuò)。

靜態(tài)成員函數(shù)不能訪問非靜態(tài)成員:

class Car {
public:
    int speed;  // 非靜態(tài)成員變量
    static int carCount;  // 靜態(tài)成員變量

    static void printSpeed() {
        // 編譯錯(cuò)誤:靜態(tài)成員函數(shù)無法訪問非靜態(tài)成員變量
        cout << "Speed: " << speed << endl;
    }
};

那為什么靜態(tài)成員函數(shù)不能訪問非靜態(tài)成員?

這個(gè)問題其實(shí)很好理解,關(guān)鍵在于靜態(tài)成員函數(shù)的“身份”問題。

1、靜態(tài)成員函數(shù)屬于類,而不是對(duì)象:靜態(tài)成員函數(shù)是在類層面上定義的,它沒有綁定到具體的對(duì)象。所以,當(dāng)你調(diào)用靜態(tài)成員函數(shù)時(shí),它是通過類名來調(diào)用的,不依賴于任何特定的對(duì)象。

2、非靜態(tài)成員屬于對(duì)象:而非靜態(tài)成員變量和普通成員函數(shù)是屬于具體對(duì)象的。當(dāng)你創(chuàng)建一個(gè)對(duì)象時(shí),非靜態(tài)成員才會(huì)存在,并且只有通過這個(gè)對(duì)象才能訪問這些成員。

靜態(tài)成員函數(shù)無法訪問非靜態(tài)成員的原因就是,它不屬于任何特定的對(duì)象,所以無法知道該訪問哪個(gè)對(duì)象的非靜態(tài)成員。換句話說,靜態(tài)成員函數(shù)沒有“this”指針,它無法指向具體的對(duì)象,也就不能訪問屬于某個(gè)對(duì)象的成員。

舉個(gè)例子來說明:

還是上面 Car 類的例子,speed 是一個(gè)非靜態(tài)成員變量,而 carCount 是一個(gè)靜態(tài)成員變量。

  • 當(dāng)你調(diào)用靜態(tài)成員函數(shù) printSpeed() 時(shí),它是通過類名來調(diào)用的。這個(gè)函數(shù)沒有“this”指針,無法知道是哪個(gè) Car 對(duì)象的 speed 變量。
  • 但是,靜態(tài)成員函數(shù)可以訪問類中的靜態(tài)成員 carCount,因?yàn)殪o態(tài)成員是屬于類的,不依賴于具體的對(duì)象。

所以,靜態(tài)成員函數(shù)只能訪問靜態(tài)成員變量和其他靜態(tài)函數(shù),無法訪問非靜態(tài)成員。

小結(jié):

靜態(tài)成員函數(shù)和對(duì)象沒關(guān)系,它不屬于某個(gè)具體對(duì)象,所以它不能直接操作對(duì)象的非靜態(tài)成員變量。

static 成員的應(yīng)用場(chǎng)景:

了解了靜態(tài)成員變量和靜態(tài)成員函數(shù)的基本概念,接下來我們來聊聊它們的實(shí)際應(yīng)用場(chǎng)景。雖然在很多情況下,我們的類對(duì)象都有自己獨(dú)立的成員變量和成員函數(shù),但在某些特定場(chǎng)景下,靜態(tài)成員就能派上大用場(chǎng)。

1. 全局共享數(shù)據(jù)

假設(shè)我們有一個(gè)程序需要統(tǒng)計(jì)不同用戶的訪問次數(shù),而這個(gè)次數(shù)應(yīng)該對(duì)所有用戶共享,而不是每個(gè)用戶都有一份。這時(shí),靜態(tài)成員變量就能幫助我們做到這一點(diǎn)。

例如,我們可以在用戶類中創(chuàng)建一個(gè)靜態(tài)的訪問計(jì)數(shù)器,所有用戶對(duì)象共享這個(gè)計(jì)數(shù)器,這樣每當(dāng)有用戶訪問時(shí),計(jì)數(shù)器就會(huì)增加,而不需要每個(gè)對(duì)象都單獨(dú)保存一份。

class User {
public:
    static int visitCount;  // 所有用戶共享

    User() {
        visitCount++;
    }
};

// 在類外定義靜態(tài)變量
int User::visitCount = 0;

int main() {
    User user1;
    User user2;
    cout << "Total visits: " << User::visitCount << endl;  // 輸出:2
    return 0;
}

在這個(gè)例子中,不管你創(chuàng)建多少個(gè) User 對(duì)象,它們都會(huì)共享同一個(gè) visitCount,這樣就避免了每個(gè)用戶對(duì)象都存儲(chǔ)計(jì)數(shù)的重復(fù)工作。

2. 工廠模式中的靜態(tài)成員

有些時(shí)候,類中的靜態(tài)成員函數(shù)可以幫助你創(chuàng)建對(duì)象。工廠模式就是一個(gè)常見的例子,它允許你通過靜態(tài)成員函數(shù)來創(chuàng)建類的實(shí)例,而不需要在外部直接調(diào)用構(gòu)造函數(shù)。

class Product {
public:
    static Product* createProduct() {
        return new Product();
    }
};

int main() {
    Product* product = Product::createProduct();
    // 使用 product
    delete product;
    return 0;
}

在這里,createProduct 是一個(gè)靜態(tài)成員函數(shù),用來創(chuàng)建 Product 對(duì)象。這種做法能夠封裝對(duì)象創(chuàng)建的細(xì)節(jié),提供更靈活的控制。

3. 配置類中的靜態(tài)成員

在很多程序中,我們可能會(huì)有一個(gè)配置類,用來保存一些全局的配置數(shù)據(jù)(如程序的設(shè)置、資源路徑、日志級(jí)別等)。這些配置信息往往是固定的,不會(huì)因?yàn)閷?duì)象的創(chuàng)建而變化。此時(shí),靜態(tài)成員變量非常適合用來保存這些共享的數(shù)據(jù)。

例如,一個(gè)全局的日志配置類可以用靜態(tài)成員來記錄當(dāng)前的日志級(jí)別:

class Logger {
public:
    static int logLevel;

    static void log(const string& message) {
        if (logLevel >= 2) {
            cout << "Log: " << message << endl;
        }
    }
};

// 在類外定義靜態(tài)變量
int Logger::logLevel = 2;

int main() {
    Logger::log("Program started");
    Logger::logLevel = 1;
    Logger::log("Another log");
    return 0;
}

在這個(gè)例子中,logLevel 是一個(gè)靜態(tài)成員,所有日志都根據(jù)這個(gè)靜態(tài)設(shè)置來決定是否輸出。

總結(jié):

靜態(tài)成員變量和靜態(tài)成員函數(shù)讓我們?cè)?C++ 中能更方便地管理共享數(shù)據(jù)和功能。它的一個(gè)關(guān)鍵特點(diǎn)是:它們屬于整個(gè)類,而不是某個(gè)具體的對(duì)象。所以,多個(gè)對(duì)象之間能共享同一份數(shù)據(jù),避免了每個(gè)對(duì)象都要獨(dú)占一份的情況。這不僅節(jié)省內(nèi)存,也讓代碼更加簡(jiǎn)潔高效。

今天我們了解了靜態(tài)成員變量和靜態(tài)成員函數(shù)的基本用法,知道了如何共享數(shù)據(jù)、訪問靜態(tài)成員,還明白了為什么靜態(tài)成員函數(shù)不能訪問非靜態(tài)的成員。

責(zé)任編輯:武曉燕 來源: 跟著小康學(xué)編程
相關(guān)推薦

2023-03-21 15:21:52

開發(fā)程序設(shè)計(jì)static

2010-01-18 18:04:28

靜態(tài)成員

2010-01-18 16:42:13

C++類

2024-02-22 18:07:17

C++靜態(tài)成員代碼

2010-02-01 17:31:06

C++類成員

2011-07-20 16:09:08

C++

2010-01-19 18:35:12

靜態(tài)成員

2023-10-07 15:53:05

C/C++靜態(tài)變量內(nèi)存

2009-05-26 09:31:00

C++重載覆蓋

2021-06-18 12:30:36

C++函數(shù)指針編程語言

2024-04-08 11:35:34

C++static關(guān)鍵字

2010-02-03 11:01:18

C++類靜態(tài)成員初始化

2010-01-21 14:19:44

C++靜態(tài)成員

2023-12-04 10:57:52

函數(shù)C++

2024-02-26 10:36:59

C++開發(fā)關(guān)鍵字

2011-08-10 17:16:01

Objective-C靜態(tài)變量

2011-04-07 16:34:05

staticC++

2010-02-03 15:27:26

C++ static

2010-01-26 15:51:06

C++變量

2010-01-13 17:28:32

SOHO交換機(jī)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)