成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

面試官最愛問的 static 陷阱:答對薪資翻倍,答錯直接掛科!

開發(fā)
在 C/C++的編程實踐中,static 關鍵字猶如瑞士軍刀般存在,它能夠控制變量和函數(shù)的生命周期、作用域、存儲方式,還能在面向對象編程中實現(xiàn)類級別的共享特性。

static 關鍵字在 C/C++當中非常非常重要,有多重要,我們先看看幾位大佬的說法:

  • 《Linux 多線程服務端編程》作者 陳碩 在書籍中多次強調(diào):"正確理解 static 的語義,是寫出高質(zhì)量 C++代碼的基本功"。
  • 《現(xiàn)代 C++編程實戰(zhàn)》作者 吳詠煒 在書籍中指出:"static 的正確使用是區(qū)分 C++程序員水平的重要標尺"。
  • Linux 內(nèi)核開發(fā)者 Robert Love 曾說:"真正理解 static 的程序員,已經(jīng)跨過了從語言使用者到系統(tǒng)設計者的門檻"。

static 關鍵字是一個看著簡單,其實有很多知識點的核心機制。可以說在 C/C++的編程實踐中,static 關鍵字猶如瑞士軍刀般存在,它能夠控制變量和函數(shù)的生命周期、作用域、存儲方式,還能在面向對象編程中實現(xiàn)類級別的共享特性。今天我們來一起復習下:萬字長文,建議收藏!

一、 C 語言中的 static

在 C 語言中,static 主要有兩種截然不同的含義,取決于它所修飾的對象(變量或函數(shù))的位置:

1. 文件作用域的 static:內(nèi)部鏈接

當 static 用于修飾在函數(shù)外部定義的全局變量或函數(shù)時,它的核心作用是改變鏈接屬性,將其從默認的外部鏈接改為內(nèi)部鏈接。

  • 外部鏈接:默認情況下,全局變量和函數(shù)具有外部鏈接。這意味著它們不僅在當前源文件(編譯單元,Translation Unit)中可見,而且可以被其他源文件通過 extern 聲明來訪問和使用。鏈接器(Linker)在鏈接多個目標文件時,會解析這些具有外部鏈接的符號名,確保它們在整個程序中是唯一的(或者說,定義只有一個)。
  • 內(nèi)部鏈接:使用 static 修飾后,全局變量或函數(shù)的名字將只在當前的源文件中可見。其他源文件即使使用 extern 聲明也無法訪問到它們。鏈接器在處理具有內(nèi)部鏈接的符號時,不會將它們暴露給其他編譯單元。

為什么需要內(nèi)部鏈接?

  • 避免命名沖突:在一個大型項目中,不同的模塊(源文件)可能會無意中定義相同名稱的全局變量或輔助函數(shù)。如果它們都具有外部鏈接,鏈接器會報告“符號重定義”錯誤。將只在模塊內(nèi)部使用的全局變量和函數(shù)聲明為 static,可以有效地將它們“隱藏”起來,避免與其他模塊的同名符號沖突。這是一種基本的封裝手段。
  • 限制作用域,提高模塊化:明確告知其他開發(fā)者(以及編譯器和鏈接器),這個變量或函數(shù)是本模塊內(nèi)部使用的,不應被外部直接依賴。這有助于降低模塊間的耦合度,提高代碼的可維護性。

示例:

// module_a.c
#include <stdio.h>

static int s_a= 0; // 內(nèi)部鏈接的全局變量,僅 module_a.c 可見
int g_b= 10;        // 外部鏈接的全局變量(默認)

static void func() {   // 內(nèi)部鏈接的函數(shù),僅 module_a.c 可見
    printf("func: %d\n", ++s_a);
}

void func2() {               // 外部鏈接的函數(shù)(默認)
    printf("func2: %d\n", g_b);
}

// module_b.c
#include <stdio.h>

// extern int s_a; // 嘗試訪問,鏈接時會失敗!error: undefined reference to `s_a`
extern int g_b;      // 可以訪問 module_a.c 中的 g_b

// extern void func(); // 嘗試訪問,鏈接時會失敗!error: undefined reference to `func`
extern void func2();         // 可以調(diào)用 module_a.c 中的 func2

int main() {
    printf("g_b: %d\n", g_b);
    func2(); // 調(diào)用 module_a 的公共函數(shù)
    // func(); // 直接調(diào)用或通過 extern 聲明調(diào)用都會失敗
    return0;
}

在這個例子中,s_a 和 func 因為 static 的修飾,被牢牢地限制在了 module_a.c 內(nèi)部,module_b.c 無法直接觸及它們,從而保證了 module_a.c 的內(nèi)部實現(xiàn)細節(jié)不被外部干擾,也避免了潛在的命名沖突。

類比思考: 

可以將源文件想象成一個房間,static 全局變量/函數(shù)就像是房間里的私人物品,只有房間內(nèi)的人(代碼)可以使用。而沒有 static 的全局變量/函數(shù)就像是放在公共走廊上的物品,所有房間的人(其他源文件)都可能看到和使用(如果知道名字的話)。

2. 函數(shù)作用域的 static:靜態(tài)存儲期

當 static 用于修飾在函數(shù)內(nèi)部定義的局部變量時,它的含義完全不同。它不再影響鏈接屬性(局部變量本來就沒有鏈接屬性),而是改變變量的存儲期。

(1) 自動存儲期

默認情況下,函數(shù)內(nèi)的局部變量具有自動存儲期。它們在程序執(zhí)行進入其作用域(通常是函數(shù)體或代碼塊)時被創(chuàng)建和初始化,在退出作用域時被銷毀。每次函數(shù)調(diào)用都會創(chuàng)建新的實例,它們的值在函數(shù)調(diào)用之間不會保留。它們通常存儲在棧上。

(2) 靜態(tài)存儲期

使用 static 修飾后,局部變量將具有靜態(tài)存儲期。這意味著:

  • 生命周期延長:變量在程序第一次執(zhí)行到其定義時被創(chuàng)建和初始化,并且會一直存活到程序結束。它的內(nèi)存通常分配在靜態(tài)存儲區(qū)(.data 或 .bss 段),而不是棧上。
  • 僅初始化一次:盡管定義語句可能在函數(shù)中,看起來每次調(diào)用都會執(zhí)行,但帶有 static 的局部變量的初始化只會在整個程序生命周期內(nèi)發(fā)生一次(通常是在第一次執(zhí)行到該定義時)。
  • 值在調(diào)用間保持:由于變量的生命周期貫穿程序始終,它在函數(shù)調(diào)用結束后不會被銷毀,其值會保留到下一次函數(shù)調(diào)用。

為什么需要靜態(tài)局部變量?

  • 維護狀態(tài):需要在函數(shù)多次調(diào)用之間保持某個狀態(tài),例如計數(shù)器、緩存、標志位等。
  • 避免重復初始化開銷:如果一個局部變量的初始化比較昂貴(例如,需要計算或分配資源),但其值在后續(xù)調(diào)用中應保持不變,使用 static 可以確保初始化只進行一次。
  • 簡單的單例模式(C 風格):雖然不完全是面向對象的單例,但可以用來確保某個資源或對象在函數(shù)內(nèi)部只被創(chuàng)建一次。

示例:

#include <stdio.h>
void counter_function() {
    static int call_count = 0; // 靜態(tài)局部變量,只初始化一次
    int auto_var = 0;          // 自動局部變量,每次調(diào)用都重新初始化

    call_count++;
    auto_var++;

  printf("Static count: %d, Auto var: %d\n", call_count, auto_var);
}
int main() {
    printf("Calling counter_function first time:\n");
    counter_function();

    printf("\nCalling counter_function second time:\n");
    counter_function();

    printf("\nCalling counter_function third time:\n");
    counter_function();
    return0;
}
/*
輸出:
Calling counter_function first time:
Static count: 1, Auto var: 1

Calling counter_function second time:
Static count: 2, Auto var: 1

Calling counter_function third time:
Static count: 3, Auto var: 1
*/

可以看到,call_count 的值在每次函數(shù)調(diào)用后都得以保留并累加,而 auto_var 則在每次調(diào)用時都重置為 1。這就是靜態(tài)存儲期和自動存儲期的關鍵區(qū)別。

注意事項:

在 C 語言的多線程環(huán)境中,如果多個線程同時調(diào)用包含靜態(tài)局部變量初始化的函數(shù),其初始化過程可能不是線程安全的(取決于編譯器實現(xiàn)和 C 標準版本,C11 之前沒有強制規(guī)定)。競態(tài)條件可能導致變量被初始化多次或初始化不完整。C++11 及之后對此有明確的線程安全保證(稍后詳述)。

總結:

C 語言當中的 static 其實就兩個功能:

  • 第一:對于全局的(變量和函數(shù))改變鏈接屬性
  • 第二:對于局部的(只有變量)改變生存周期。

注意的是,static 全局內(nèi)容不要放在頭文件,我們需要知道,頭文件用于共享聲明,這里重點是共享,而 static 全局內(nèi)容用于修改鏈接屬性為內(nèi)部鏈接,反對共享!這兩者本質(zhì)上就是相對的。

雖然 static 全局內(nèi)容放到了頭文件不會出錯,但是會導致所有引用這個頭文件的翻譯單元都會有一份副本。這么寫,很大可能是對 static 理解不到位,一般沒有任何意義,達不到預想的效果。

如果你是想要所有翻譯單元訪問同一份資源,那應該用 extern 頭文件聲明+源文件定義的方式。

如果你是想要各自翻譯單元有自己的資源,但是資源名字一樣,那么應該在源文件中分別定義自己的 static 全局資源(這個也不是推薦的寫法)。

二、 C++ 中的 static

C++ 完全繼承了 C 語言中 static 的上述兩種用法(內(nèi)部鏈接和靜態(tài)局部變量),但也對其進行了一些演進,并賦予了它在類(Class)中的全新、重要的含義。

1. 繼承自 C 的用法及其演進

內(nèi)部鏈接(文件/命名空間作用域):

  • static 仍然可用:你仍然可以在 C++ 的全局作用域或命名空間作用域使用 static 來定義具有內(nèi)部鏈接的變量和函數(shù)。其效果與 C 語言中完全相同。
  • 匿名命名空間是更推薦的方式:然而,在 C++ 中,強烈推薦使用匿名命名空間來替代 static 實現(xiàn)內(nèi)部鏈接。
// C++ 推薦方式: 匿名命名空間
namespace { // <--- 匿名命名空間開始
    int internal_counter = 0; // 默認具有內(nèi)部鏈接

    void internal_helper() {  // 默認具有內(nèi)部鏈接
        // ...
    }
} // <--- 匿名命名空間結束

// C++ 不推薦方式 (但仍然有效): static
// static int old_style_counter = 0;
// static void old_style_helper() { /* ... */ }

void public_api() {
    internal_helper(); // 可以直接調(diào)用同一編譯單元內(nèi)的匿名命名空間成員
}

為什么使用匿名命名空間:

  • 一致性:它使用 C++ 的核心語言特性(命名空間)來解決作用域問題,而不是依賴一個具有多重含義的關鍵字。
  • 適用性更廣:匿名命名空間不僅可以用于變量和函數(shù),還可以用于類型定義(如 class, struct, enum, typedef, using 別名等)。static 不能用于限制類型的鏈接屬性。
  • 清晰性:代碼意圖更明確,namespace { ... } 清晰地標示出一塊內(nèi)部使用的區(qū)域。
  • 避免 static 歧義:減少 static 關鍵字的負擔,讓它主要承擔在類中和函數(shù)內(nèi)的角色。

正如吳詠煒老師可能強調(diào)的,擁抱現(xiàn)代 C++ 的實踐,選擇更清晰、更通用的語言特性。

靜態(tài)局部變量(函數(shù)作用域):

  • 用法和 C 類似:在 C++ 函數(shù)內(nèi)部使用 static 定義局部變量,其效果(靜態(tài)存儲期、僅初始化一次、值在調(diào)用間保持)與 C 語言基本一致。
  • C++11 及以后的線程安全初始化保證(Magic Statics):這是一個重大的改進。C++11 標準規(guī)定,靜態(tài)局部變量的初始化是線程安全的。這意味著即使多個線程可能同時首次執(zhí)行到該 static 變量的定義處,C++ 運行時環(huán)境會確保初始化過程只發(fā)生一次,并且其他線程會等待初始化完成后才能繼續(xù)執(zhí)行。這極大地簡化了在多線程環(huán)境下使用靜態(tài)局部變量(例如實現(xiàn)線程安全的單例模式)的代碼。

示例:

#include <iostream>
#include <thread>
#include <vector>

class Singleton {
public:
    static Singleton& getInstance() {
        // C++11 guarantees thread-safe initialization for function-local statics
        static Singleton instance; // "Magic Static"
        std::cout << "獲取單例線程:thread " << std::this_thread::get_id() << std::endl;
        return instance;
    }

    void showMessage() {
        std::cout << "單例調(diào)用:(" << this << ") says hello!" << std::endl;
    }

private:
    Singleton() {
        // Simulate complex initialization
        std::cout << "單例創(chuàng)建: thread "
            << std::this_thread::get_id() << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }
    ~Singleton() = default;
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
};

void worker() {
    Singleton::getInstance().showMessage();
}

int main() {
    std::vector<std::thread> threads;
    std::cout << "Creating threads..." << std::endl;
    for (int i = 0; i < 5; ++i) {
        threads.emplace_back(worker);
    }

    for (auto& t : threads) {
        t.join();
    }
    std::cout << "All threads finished." << std::endl;
    return0;
}

運行輸出:(VS2022)

Creating threads...
單例創(chuàng)建: thread39972
獲取單例線程:thread25656
單例調(diào)用:(00007FF79E478440)sayshello!
獲取單例線程:thread39708
單例調(diào)用:(00007FF79E478440)sayshello!
獲取單例線程:thread39972
單例調(diào)用:(00007FF79E478440)sayshello!
獲取單例線程:thread5280
單例調(diào)用:(00007FF79E478440)sayshello!
獲取單例線程:thread1744
單例調(diào)用:(00007FF79E478440)sayshello!
Allthreadsfinished.

2. C++ 類(Class)中的 static

這是 static 在 C++ 中獨有的、至關重要的用法。當 static 用于修飾類的成員時,它表示該成員屬于類本身,而不是類的任何特定對象(實例)。

靜態(tài)成員變量:

  • 共享性:靜態(tài)成員變量是該類所有對象共享的。無論創(chuàng)建了多少個類的對象,或者即使沒有創(chuàng)建任何對象,靜態(tài)成員變量都只有一份內(nèi)存副本。
  • 生命周期:它們具有靜態(tài)存儲期,在程序啟動時(或首次使用前,取決于具體情況和編譯優(yōu)化)被創(chuàng)建和初始化,直到程序結束才銷毀。它們不存儲在對象實例的內(nèi)存布局中。
  • 作用域:它們屬于類的作用域,訪問時需要使用類名和作用域解析運算符 ::(ClassName::staticVar),或者通過類的對象或指針/引用訪問(object.staticVar 或 ptr->staticVar),但推薦使用類名訪問以強調(diào)其類成員的身份。

定義與初始化:

  • 通常需要在類定義外部進行定義和初始化。在類定義內(nèi)部只是聲明。這一定義通常放在對應的 .cpp 源文件中,以確保它只被定義一次(符合 ODR - One Definition Rule)。
  • 例外:const static 整型/枚舉成員(C++11 前)或 constexpr static 成員(C++11 起):如果一個靜態(tài)成員變量是 const 的整型(int, char, bool 等)或枚舉類型,可以在類定義內(nèi)部直接初始化。C++11 引入 constexpr 后,constexpr static 成員也可以在類內(nèi)部初始化(且其值在編譯期可知)。
  • C++17 的 inline static 成員:C++17 引入了 inline 關鍵字用于靜態(tài)成員變量,允許在類定義內(nèi)部直接完成定義和初始化,即使對于非 const 或非 constexpr 的類型。這極大地簡化了靜態(tài)成員變量的使用,尤其是在頭文件(header-only)庫中。

示例:

// counter.h
class ObjectCounter {
public:
    ObjectCounter() {
        s_count++; // 對象創(chuàng)建時,共享計數(shù)器加 1
    }
    ~ObjectCounter() {
        s_count--; // 對象銷毀時,共享計數(shù)器減 1
    }

    // 聲明靜態(tài)成員變量
    static int s_count;

    // C++17: inline static member (可在頭文件定義和初始化)
    inline static double s_version = 1.0;

    // const static integral member (可在類內(nèi)初始化)
    const static int s_maxObjects = 100;

    // constexpr static member (C++11, 可在類內(nèi)初始化, 編譯期常量)
    constexpr static const char* s_typeName = "ObjectCounter";

    static int getCount() { return s_count; } // 靜態(tài)成員函數(shù)訪問靜態(tài)成員變量
};

// counter.cpp (如果不用 inline static,需要在這里定義非 const/constexpr static 成員)
// #include "counter.h"
// int ObjectCounter::s_count = 0; // 定義并初始化 s_count

用途: 類范圍的常量、所有對象共享的狀態(tài)(如對象計數(shù)器、共享資源指針)、配置參數(shù)等。

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

  • 屬于類,不依賴對象:靜態(tài)成員函數(shù)也是屬于類本身的,調(diào)用它們不需要創(chuàng)建類的對象。
  • 無 this 指針:最關鍵的區(qū)別在于,靜態(tài)成員函數(shù)沒有隱式的 this 指針。因為它們不與任何特定對象關聯(lián)。
  • 訪問限制:由于沒有 this 指針,靜態(tài)成員函數(shù)不能直接訪問類的非靜態(tài)成員(變量或函數(shù))。它們只能直接訪問類的其他靜態(tài)成員(靜態(tài)變量和靜態(tài)函數(shù))。如果需要訪問非靜態(tài)成員,必須通過傳遞一個對象實例的引用或指針來實現(xiàn)。
  • 調(diào)用方式:通常使用類名和作用域解析運算符 :: 調(diào)用(ClassName::staticFunc())。也可以通過對象或指針/引用調(diào)用(object.staticFunc() 或 ptr->staticFunc()),但這會掩蓋其靜態(tài)本質(zhì),不推薦。

示例(續(xù)上例):ObjectCounter::getCount() 就是一個靜態(tài)成員函數(shù)。它不需要對象實例即可調(diào)用,并且它直接訪問了靜態(tài)成員變量 s_count。

// 在 main.cpp 或其他地方:
int currentCount = ObjectCounter::getCount(); // 正確調(diào)用

另一個例子:工廠方法

#include <string>
#include <memory>
class Resource {
public:
    // 靜態(tài)工廠方法
    static std::unique_ptr<Resource> create(const std::string& type) {
        if (type == "TypeA") {
            return std::unique_ptr<Resource>(new Resource("Created TypeA"));
        } else if (type == "TypeB") {
            return std::unique_ptr<Resource>(new Resource("Created TypeB"));
        }
        return nullptr;
    }
    void use() { /* ... use resource ... */ }
    const std::string& getInfo() const { return info_; }
private:
    // 私有構造函數(shù),強制通過工廠方法創(chuàng)建
    Resource(std::string info) : info_(std::move(info)) {}
    std::string info_;
    // 禁止拷貝和賦值
    Resource(const Resource&) = delete;
    Resource& operator=(const Resource&) = delete;
};
int main() {
    auto resA = Resource::create("TypeA"); // 使用靜態(tài)工廠方法創(chuàng)建對象
    if (resA) {
        std::cout << "Resource A info: " << resA->getInfo() << std::endl;
        resA->use();
    }
    auto resB = Resource::create("TypeB");
    if (resB) {
        std::cout << "Resource B info: " << resB->getInfo() << std::endl;
    }
    return 0;
}

在這個工廠模式的例子中,create 函數(shù)作為靜態(tài)成員函數(shù),負責根據(jù)輸入?yún)?shù)創(chuàng)建并返回 Resource 對象(通過智能指針管理)。它屬于 Resource 類,但調(diào)用時不需要先有一個 Resource 對象。

用途: 工具函數(shù)只操作靜態(tài)成員或與類概念相關但不需要對象狀態(tài)、工廠方法、管理靜態(tài)成員變量等。

類比思考: 

想象一個班級(Class。靜態(tài)成員變量就像是班級的公告欄(s_count),上面記錄著全班的總人數(shù),所有學生(對象)共享這個信息。靜態(tài)成員函數(shù)就像是班主任(getCount),他可以查看和更新公告欄信息,但他的行動不依賴于某個特定的學生(沒有 this)。而非靜態(tài)成員變量就像是每個學生的書包(instance_data),里面裝著各自的東西。非靜態(tài)成員函數(shù)就像是學生自己整理書包(instance_method()),需要明確是哪個學生(this)在操作自己的書包。

三、 static 用法異同點總結

用法上下文

C 語言

C++ 語言

核心含義/作用

文件/全局/命名空間作用域

static 全局變量/函數(shù): 內(nèi)部鏈接 (限制在當前編譯單元)


1. static 全局/命名空間變量/函數(shù): 內(nèi)部鏈接 (效果同 C,但不推薦) 
 2. 匿名命名空間: 提供內(nèi)部鏈接 (C++ 推薦方式)

控制符號的可見性,避免命名沖突,實現(xiàn)封裝

函數(shù)內(nèi)部

static 局部變量: 靜態(tài)存儲期 (生命周期延長至程序結束,僅初始化一次)


static 局部變量:

1、靜態(tài)存儲期 (同 C) 
2、C++11 起保證線程安全初始化 

使局部變量在函數(shù)調(diào)用間保持狀態(tài),只初始化一次

C++ 類定義內(nèi)部

不適用

1. static 成員變量: 屬于類,所有對象共享,靜態(tài)存儲期 
2. static 成員函數(shù): 屬于類,無 this 指針,只能直接訪問靜態(tài)成員

定義類級別的屬性和行為,獨立于特定對象實例

四、 實踐中的考量與建議

(1) 優(yōu)先使用匿名命名空間而非 static 實現(xiàn)內(nèi)部鏈接 (C++):這是現(xiàn)代 C++ 的慣例。它更清晰、更通用,能覆蓋類型定義,且避免了 static 關鍵字的語義過載。static 在全局/命名空間作用域應視為 C 的遺留用法。

(2) 警惕全局/命名空間作用域的 static 變量 (C/C++):雖然 static 或匿名命名空間能限制其鏈接性,但它們本質(zhì)上仍是全局狀態(tài)。全局狀態(tài)往往使程序的依賴關系復雜化,難以推理和測試,尤其在多線程環(huán)境下容易引入競態(tài)條件(除非精心設計同步)。陳碩在 muduo 庫的設計中就強調(diào)避免不必要的全局變量。優(yōu)先考慮將狀態(tài)封裝在對象中,通過參數(shù)傳遞或成員變量來管理。

(3) 善用函數(shù)內(nèi)的 static 變量 (C++):C++11 的線程安全初始化保證使其成為實現(xiàn)簡單單例或緩存的便捷方式。但要注意,它們的生命周期是整個程序,如果它們持有復雜資源(如文件句柄、網(wǎng)絡連接),需要考慮程序退出時的資源釋放問題(雖然通常操作系統(tǒng)會回收,但顯式管理更佳)。

(4) 靜態(tài)變量的初始化順序問題:如果一個靜態(tài)變量的初始化依賴于另一個編譯單元中的靜態(tài)存儲期變量(全局或局部),可能會遇到"靜態(tài)初始化順序災禍" 。

// a.cpp
int global_var = initSomething();
// b.cpp
static int static_var = global_var;  // 危險!

記住:永遠不要在不同編譯單元之間建立靜態(tài)初始化依賴關系。

函數(shù)內(nèi)的靜態(tài)變量由于其延遲初始化(第一次調(diào)用時)特性,可以在一定程度上緩解這個問題,但跨編譯單元的依賴仍需小心。盡量避免復雜的靜態(tài)初始化依賴。C++標準明確規(guī)定:不同編譯單元中的全局變量和靜態(tài)變量的初始化順序是未定義的。

(5) 理解 static 類成員的生命周期和定義位置:切記非 inline、非 const static integral/constexpr static 的靜態(tài)成員變量需要在類外定義。忘記定義是常見的鏈接錯誤來源。C++17 的 inline static 簡化了這一點,值得在新代碼中采用。

(6) 明確 static 成員函數(shù)與非靜態(tài)成員函數(shù)的區(qū)別:核心在于 this 指針的有無。調(diào)用靜態(tài)成員函數(shù)時腦中要繃緊一根弦:它不屬于任何對象。這決定了它能訪問哪些成員。

(7) static 與 const / constexpr 結合:

  • static const 全局/命名空間變量:提供內(nèi)部鏈接的常量。
  • static constexpr (C++11): 提供內(nèi)部鏈接的編譯期常量。
  • static const 類成員:類范圍的運行時常量(若非整型/枚舉/inline/constexpr,需類外定義)。
  • static constexpr 類成員 (C++11): 類范圍的編譯期常量(可在類內(nèi)定義)。

五、 結語

理解 static 的每一種含義,區(qū)分它們在 C 和 C++ 中的細微差別(尤其是 C++11/17 帶來的改進和類相關的用法),并遵循最佳實踐(如優(yōu)先使用匿名命名空間、注意線程安全、警惕全局狀態(tài)),是我們作為 C/C++ 開發(fā)者提升代碼質(zhì)量和設計能力的必經(jīng)之路。建議讀一讀陳碩大神的書籍,里面很多 static 的設計寫法值得學習!

責任編輯:趙寧寧 來源: CppPlayer
相關推薦

2025-06-30 01:55:00

2025-06-03 07:05:00

Linux操作系統(tǒng)Windows

2018-01-19 10:43:06

Java面試官volatile關鍵字

2021-03-17 08:39:24

作用域作用域鏈JavaScript

2025-03-18 12:00:00

閉包JavaScript前端

2025-02-10 00:00:25

內(nèi)存管理開發(fā)

2023-09-26 00:37:38

Spring微服務框架

2025-05-12 10:10:00

運維Linux系統(tǒng)

2021-11-08 09:18:01

CAS面試場景

2021-12-25 22:31:10

MarkWord面試synchronize

2021-12-16 18:38:13

面試Synchronize

2021-12-02 18:20:25

算法垃圾回收

2020-07-28 00:58:20

IP地址子網(wǎng)TCP

2010-08-23 15:06:52

發(fā)問

2021-01-06 05:36:25

拉鏈表數(shù)倉數(shù)據(jù)

2022-01-05 09:55:26

asynawait前端

2021-04-21 09:28:17

字節(jié)面試官SetTimeout

2024-08-19 09:13:02

2024-06-04 07:38:10

2025-03-05 08:04:31

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲毛片 | 国产高清在线 | 久久久国产视频 | 亚洲视频在线一区 | 亚洲 欧美 日韩 在线 | 欧美一区免费 | 日韩色图视频 | 日韩精品一区二区三区中文字幕 | 毛片电影| 欧美日韩在线国产 | 日本又色又爽又黄的大片 | 免费国产视频 | 乳色吐息在线观看 | 一级午夜aaa免费看三区 | 我要看黄色录像一级片 | 久国久产久精永久网页 | 波多野结衣一区二区 | 日韩国产一区 | 成人福利网站 | 麻豆视频在线看 | 在线观看黄免费 | 午夜精品一区二区三区免费视频 | 国产视频一区二区 | 国产一区二区三区高清 | 欧美性受xxxx白人性爽 | 精品九九九 | 日韩国产中文字幕 | 国产在线播放一区二区三区 | 亚洲 中文 欧美 | 日韩1区| 69视频在线播放 | 亚洲 欧美 日韩在线 | 国产91黄色 | 久久国产区 | 欧美1区| 亚洲视频自拍 | xx视频在线观看 | 欧美成人精品在线 | 资源首页二三区 | 人人cao | 午夜影院网站 |