精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

C++ 老鳥的膝蓋收割機:一文看穿 inline 變量如何暴打傳統 extern 方案!

開發
C++17 的 inline 變量,是通過修改 ODR 規則來允許在頭文件中定義。這極大地簡化了代碼組織,特別是對于需要在頭文件中提供全局實體的場景。

C++17 的inline變量是一個重要的改進,它解決了如何在頭文件中定義全局/靜態變量的難題。

我們先回顧下 在沒有inline變量(C++17 之前)的情況下,嘗試在頭文件中定義一個全局變量會遇到什么問題,以及當時的解決方案是什么。

場景: 假設我們想定義一個全局配置變量,比如一個日志級別 logLevel,希望整個程序都能訪問和修改這同一個變量。我們很自然地想把它放在一個頭文件 config.h 中,這樣所有需要它的 .cpp 文件都可以包含它。

嘗試一:直接在頭文件中定義 (錯誤方式)

// config.h
#ifndef CONFIG_H
#define CONFIG_H

int logLevel = 0; // 嘗試直接定義全局變量

#endif // CONFIG_H

// logger.cpp
#include "config.h"
#include <iostream>
void logMessage(int level, constchar* msg){
    if (level >= logLevel) {
        std::cout << msg << std::endl;
    }
}

// main.cpp
#include "config.h"
#include <iostream>
void logMessage(int level, constchar* msg); // 假設在別處聲明

int main(){
    logLevel = 1; // 設置日志級別
    std::cout << "Current log level: " << logLevel << std::endl;
    logMessage(0, "Info message");   // 應該打印
    logMessage(2, "Debug message");  // 不應該打印
    return0;
}

問題:

  • 當編譯 logger.cpp 時,編譯器會生成一個目標文件 logger.o。在這個目標文件里,有一個名為 logLevel 的全局變量的定義。
  • 當編譯 main.cpp 時,編譯器會生成另一個目標文件 main.o。在這個目標文件里,也有一個名為 logLevel 的全局變量的定義。

當鏈接器(Linker)試圖把 logger.o 和 main.o (以及其他可能的目標文件) 鏈接成最終的可執行文件時,它會發現兩個不同的地方都定義了同一個全局符號 logLevel。這違反了單一定義原則 (ODR)中關于非inline外部鏈接實體的規定(一個程序中只能有一個定義)。鏈接器不知道該用哪個定義,于是報錯,通常是類似 multiple definition of 'logLevel' 的錯誤。

嘗試二:在頭文件中使用 static (錯誤理解)

有人可能會想,用static關鍵字可以限制作用域,是不是能解決問題?

// config.h
#ifndef CONFIG_H
#define CONFIG_H

static int logLevel = 0; // 使用 static

#endif // CONFIG_H

// logger.cpp (同上)
// main.cpp (同上)

問題:

static用在全局/命名空間作用域時,它給予變量內部鏈接 (Internal Linkage)。這意味著:

  • logger.cpp 包含 config.h 后,會擁有自己專屬的一個 logLevel 變量,這個變量只在 logger.cpp 這個翻譯單元內部可見和有效。
  • main.cpp 包含 config.h 后,也會擁有自己專屬的另一個 logLevel 變量,這個變量只在 main.cpp 這個翻譯單元內部可見和有效。

它們是兩個完全獨立、內存地址不同的變量!在 main.cpp 中修改 logLevel,并不會影響 logger.cpp 中的那個 logLevel。這顯然不是我們想要的"整個程序共享同一個實例"的目標。鏈接器不會報錯,因為沒有外部鏈接符號沖突,但程序的邏輯是錯誤的。

C++17 之前的標準解決方案:extern 聲明 + 單獨 .cpp 定義

這是在 C++17 之前,正確實現"頭文件提供接口,程序共享單一實例"的標準做法:

  • 頭文件 (config.h): 只聲明變量,使用 extern 關鍵字。extern 告訴編譯器:“這個變量存在,但它的定義在別處(其他某個 .cpp 文件中)。你只需要知道它的類型和名字即可。” 這不會產生定義。
// config.h
#ifndef CONFIG_H
#define CONFIG_H

extern int logLevel; // 聲明:logLevel 存在,類型是 int,具有外部鏈接

#endif // CONFIG_H

  • 源文件 (config.cpp): 在一個且僅一個.cpp 文件中提供變量的定義和初始化。
// config.cpp
#include "config.h" // 最好包含頭文件以確保聲明和定義匹配
int logLevel = 0; // 定義并初始化 logLevel,這是程序中唯一的定義

  • 其他源文件 (logger.cpp, main.cpp): 包含頭文件 config.h。
// logger.cpp
#include "config.h"
// ... 使用 logLevel ...

// main.cpp
#include "config.h"
// ... 使用 logLevel ...

工作原理:

  • logger.cpp 和 main.cpp 編譯時,看到 extern int logLevel,知道有這么個變量,但不會創建它。它們生成的目標文件 logger.o 和 main.o 會記錄下它們需要一個名為 logLevel 的外部符號。
  • config.cpp 編譯時,生成 config.o,其中包含了 logLevel 的實際定義和內存分配。
  • 鏈接器在鏈接 logger.o, main.o, config.o 時,看到 logger.o 和 main.o 都需要 logLevel,然后它在 config.o 中找到了這個符號的唯一定義。于是,鏈接器將所有對 logLevel 的引用都指向 config.o 中定義的那個唯一的內存位置。

這種 extern+ .cpp 方式的缺點:

  • 麻煩:為了定義一個全局變量,你需要至少兩個文件(.h 和 .cpp)。
  • 對頭文件庫 (Header-Only Libraries) 不友好:頭文件庫的設計目標是用戶只需 #include 相應的頭文件即可使用,不需要額外鏈接庫文件或編譯作者提供的 .cpp 文件。如果庫需要定義全局狀態,這種模式就破壞了 header-only 的便利性。用戶必須手動創建一個 .cpp 文件來實例化庫的這些 extern 變量,或者庫作者必須提供一個需要編譯的源文件。

C++17 inline 變量如何解決這個問題

C++17 擴展了 inline 關鍵字,使其不僅能用于函數,也能用于變量。

// config.h (C++17 及以后)
#ifndef CONFIG_H
#define CONFIG_H

inlineint logLevel = 0; // 使用 inline 直接在頭文件中定義!

// 對于常量,也可以用 inline (或者 constexpr 本身就隱式 inline)
inlineconstdouble PI = 3.14159;

// 對于類的靜態成員變量,同樣適用
classAppSettings {
public:
    inlinestaticbool verboseMode = false;
    // C++17 起,非 const static 成員也可以在類內用 inline 初始化
};

#endif // CONFIG_H

// logger.cpp
#include "config.h"
// ... 使用 logLevel, AppSettings::verboseMode ...

// main.cpp
#include "config.h"
#include <iostream>
// ... 使用 logLevel, AppSettings::verboseMode ...

intmain(){
    logLevel = 1;
    AppSettings::verboseMode = true;
    std::cout << "Log level: " << logLevel << ", Verbose: " << AppSettings::verboseMode << std::endl;
    // ...
    return0;
}

工作原理:

  • 當 logger.cpp 包含 config.h 并編譯時,它會遇到 inline int logLevel = 0;。因為有 inline,編譯器知道這是一個定義,但它是一個特殊的"inline 定義"。它會在 logger.o 中生成 logLevel 的定義。
  • 當 main.cpp 包含 config.h 并編譯時,同樣會在 main.o 中生成 logLevel 的定義。

關鍵來了: 當鏈接器處理 logger.o 和 main.o 時,它看到多個名為 logLevel 的符號定義。但是,因為這些定義都被標記為 inline,鏈接器應用了與 inline 函數相同的 ODR 規則: 它檢查所有這些 inline 定義是否完全相同(類型、初始值等必須一致)。 

如果所有定義都相同,鏈接器被允許(并且通常會)選擇其中任意一個定義作為最終程序中該變量的唯一定義,并丟棄所有其他的副本。所有對 logLevel 的引用最終都會指向這個被選中的、唯一的內存實例。

如果定義不相同(比如一個文件是 inline int logLevel = 0; 另一個是 inline int logLevel = 1; 或者類型不同),那么程序的行為是未定義 (Undefined Behavior),這是非常危險的,必須避免!編譯器和鏈接器不保證能捕捉到這種不一致。

inline 變量的優勢:

  • 簡潔:你可以在頭文件中直接定義全局變量或靜態成員變量,只需一個 inline 關鍵字,不再需要分離 .h 和 .cpp 文件。
  • Header-Only 友好:這使得創建真正只需要包含頭文件的庫變得極其方便,即使這些庫需要定義全局狀態或共享常量。
  • 概念統一:inline 對于函數和變量的行為邏輯是一致的(都允許在多個翻譯單元有相同定義,由鏈接器合并)。

總結一下

C++17 之前的 extern + .cpp 定義模式,是通過聲明與定義分離來滿足 ODR(全局只有一個定義)。

C++17 的 inline 變量,是通過修改 ODR 規則來允許在頭文件中定義。它告訴鏈接器:"嘿,你會看到這個變量的多個定義,這是合法的,只要它們都一樣,你就把它們合并成一個就行了。" 這極大地簡化了代碼組織,特別是對于需要在頭文件中提供全局實體的場景。

C++17 之前,inline 主要用于函數,有兩個主要目的:

  • 內聯提示(Hint for Inlining): 建議編譯器將函數調用替換為函數體本身,以減少函數調用開銷(但這只是一個建議,編譯器可以忽略)。
  • 違反 ODR(One Definition Rule)的豁免: 允許多個翻譯單元(.cpp 文件)包含 相同 的函數定義(通常是通過頭文件包含)。鏈接器會確保最終程序中只保留該函數的一個定義。
責任編輯:趙寧寧 來源: CppPlayer
相關推薦

2021-05-15 09:13:05

虛擬貨幣加密貨幣幣圈

2022-03-17 18:47:38

用友U9 cloud

2023-08-17 16:15:57

機器人農業機器人

2023-11-27 19:35:01

C++extern

2024-01-24 11:35:28

C++多返回值開發

2021-09-09 17:05:36

C++智能指針語言

2020-12-03 10:14:12

乒乓球機器人

2021-09-07 05:02:50

C++ConstexprConst

2010-01-26 15:51:06

C++變量

2023-09-17 22:50:23

C++編程

2021-01-27 09:34:51

Visual C++Dev C++codelite

2022-04-08 09:01:14

CSS自定義屬性前端

2022-04-12 10:34:05

Web框架方案

2025-04-27 01:00:22

2024-12-23 12:00:00

C++線程join

2011-04-21 16:57:56

staticextern

2020-11-24 10:13:02

Redis集群數據庫

2021-03-25 07:44:39

C++異常處理開發技術

2020-09-24 16:05:44

C語言sqlite3函數

2010-01-25 10:25:19

C++變量
點贊
收藏

51CTO技術棧公眾號

国产精品迅雷| 在线播放亚洲精品| 日本久久伊人| 性久久久久久久| 欧美福利精品| 99久久精品免费看国产交换| 亚洲理伦在线| 最新国产成人av网站网址麻豆| 国产一级特黄a大片免费| 精品自拍一区| 91在线视频官网| 国产成人激情小视频| 亚洲AV成人无码精电影在线| 国产精品久久久久av蜜臀 | 国产精品 欧美激情| 成人动态视频| 欧美日韩精品免费| 日本人体一区二区| 亚洲成人影院麻豆| eeuss影院一区二区三区| 国产精品久久久久999| 欧美极品aaaaabbbbb| 精品av一区二区| 欧美成人精品3d动漫h| 中文字幕无码不卡免费视频| 久久国产精品黑丝| 欧美激情一区二区三区四区| 精品久久sese| 99久久久国产精品无码免费| 午夜一区不卡| 久久久久久久国产精品视频| 国产尤物在线播放| 国产精品中文字幕亚洲欧美| 亚洲国产精品99| 国产无遮挡猛进猛出免费软件 | 亚洲制服丝袜av| 亚洲视频在线二区| 国产三级在线免费观看| 国产不卡高清在线观看视频| 国产精品羞羞答答| 中文字幕精品无码一区二区| 伊人久久久大香线蕉综合直播| 久久亚洲国产成人| 国产白丝一区二区三区| 国产区精品区| 亚洲毛片在线观看| 醉酒壮男gay强迫野外xx| www国产精品| 日韩精品专区在线影院重磅| 宇都宫紫苑在线播放| 宅男噜噜噜66国产精品免费| 欧美三电影在线| 亚洲一区在线不卡| 成人性片免费| 欧美日韩久久久久久| 成人性视频欧美一区二区三区| 在线天堂中文资源最新版| 午夜精品视频一区| 鲁一鲁一鲁一鲁一色| 激情视频网站在线播放色| 亚洲一区二区三区美女| 岛国大片在线播放| 极品在线视频| 日韩欧美一区二区在线| 国产99久久九九精品无码| 午夜影院在线观看国产主播| 色综合天天综合网天天狠天天| 无码精品国产一区二区三区免费| 精品国产免费人成网站| 91成人国产精品| 视色视频在线观看| 国产精品久久久久久久久久辛辛| 日韩亚洲欧美综合| 性xxxxxxxxx| 清纯唯美亚洲经典中文字幕| 国产视频在线观看一区二区| 性高潮久久久久久久| 欧美日韩第一| 久久久精品国产一区二区| 免费中文字幕在线观看| 一本色道精品久久一区二区三区 | 亚洲欧洲日产国产网站| 极品人妻videosss人妻| 99久久精品网| 午夜精品久久久久久久99热浪潮| 中文字字幕在线中文| 日本欧美在线观看| 亚洲自拍偷拍区| 色欲av永久无码精品无码蜜桃| 久久久久国产一区二区三区四区 | 精品二区久久| 日av在线播放中文不卡| 一区二区国产欧美| 成人av在线播放网址| 日韩精品不卡| 后进极品白嫩翘臀在线播放| 色婷婷一区二区三区四区| 欧美大片久久久| 欧美大奶一区二区| 最新国产成人av网站网址麻豆| 国产性一乱一性一伧一色| 久久久久久久欧美精品| 亚洲iv一区二区三区| 色哟哟在线观看| 综合欧美亚洲日本| 成人久久久久久久久| 免费一级欧美在线大片| 亚洲人精品午夜在线观看| 青青草原在线免费观看| 肉肉av福利一精品导航| 91久久精品美女高潮| 视频一区二区在线播放| 一区二区三区在线免费播放| av无码精品一区二区三区| 亚洲**毛片| 中文字幕不卡av| 影音先锋亚洲天堂| 国产盗摄女厕一区二区三区| 亚洲国产欧洲综合997久久| 川上优av中文字幕一区二区| 欧美一区二区视频在线观看2020| 欧美激情aaa| 亚洲经典视频在线观看| 亚洲一区二区少妇| 素人av在线| 在线观看不卡一区| 亚洲制服丝袜在线播放| 狠狠综合久久av一区二区老牛| 成人动漫网站在线观看| 国产毛片在线看| 狠狠色狠狠色综合日日五| 又大又长粗又爽又黄少妇视频| 99视频精品视频高清免费| 国产精品h片在线播放| 亚洲欧美日韩精品永久在线| 亚洲高清免费观看高清完整版在线观看| 亚洲精品第三页| 香港欧美日韩三级黄色一级电影网站| 国产精品久久久久久久9999| 欧美成人免费| 精品国产1区2区| 人妻av一区二区| 精品不卡视频| 懂色一区二区三区av片| 婷婷在线播放| 日韩欧美一级精品久久| 日本妇女毛茸茸| 国产成人在线视频网址| 国产小视频免费| 在线播放一区二区精品视频| 欧美日韩成人精品| 精品国产18久久久久久| 亚洲精品久久7777| 亚洲精品视频三区| 亚洲综合中文| 波多野结衣精品久久| 密臀av在线| 亚洲国产成人精品久久| 久久久久久久久久久久久av| 久久婷婷一区二区三区| 日韩无套无码精品| 日韩电影免费在线观看| 成人欧美在线观看| 色婷婷av在线| 亚洲国产精品va在线看黑人动漫| 国产做受高潮漫动| 久久综合九色综合97婷婷| 日本xxxxxxx免费视频| 操欧美老女人| 91免费版网站入口| 大黄网站在线观看| 亚洲理论在线a中文字幕| 伊人久久久久久久久久久久| 国产精品区一区二区三| 婷婷激情综合五月天| 欧美激情一级片一区二区| 国产一区二区久久久| 粉嫩一区二区| 精品国产一区久久久| 高潮毛片7777777毛片| 欧美性生交大片免费| 欧美一区二区三区粗大| 国产一区二区视频在线播放| 成人午夜免费在线| 精品欧美久久| 成人午夜电影在线播放| 成人美女大片| 久久夜色精品国产亚洲aⅴ| 东京干手机福利视频| 日韩欧美成人网| 国语对白在线播放| 99riav一区二区三区| 自拍偷拍21p| 亚洲精品日本| 欧美少妇一级片| 日韩黄色网络| 91亚洲精华国产精华| 亚洲校园激情春色| 欧美成人午夜激情| 国产一级免费在线观看| 欧美成人精精品一区二区频| 国产精品xxxxxx| 午夜欧美大尺度福利影院在线看 | 一区二区三区在线不卡| 受虐m奴xxx在线观看| 国产成人在线视频免费播放| 狠狠热免费视频| 日韩亚洲在线| 一本大道东京热无码aⅴ| 精品精品99| 精品网站在线看| 国产精品一区二区三区av| 国产91色在线免费| xxxx另类黑人| 久久天天躁狠狠躁夜夜爽蜜月 | 久久久久久久精| 中文字幕99页| 国产一区二区在线视频| 亚洲人辣妹窥探嘘嘘| 国产精品人人爽人人做我的可爱| 91精品一区二区三区四区| 成人精品久久| 欧美色图亚洲自拍| 国偷自产av一区二区三区| 国产精品美女网站| 欧美7777| 欧美一级高清免费播放| 国产三级伦理在线| 欧美wwwxxxx| 国产成人l区| 精品国产欧美一区二区五十路| 国产福利第一视频在线播放| 日韩精品在线视频观看| 欧洲成人一区二区三区| 日韩欧美一级二级三级久久久| 国产男男gay体育生白袜| 欧美日韩综合不卡| 在线视频精品免费| 91福利视频网站| 国产精品久久久久久久久久精爆| 黄色成人在线播放| 日韩乱码在线观看| 亚洲成人精品一区二区| 久久精品欧美一区二区| 亚洲最新视频在线观看| 美女毛片在线观看| 中文字幕综合网| 91在线播放观看| 亚洲综合激情网| 欧美日韩成人免费观看| 亚洲主播在线播放| 日韩欧美三级在线观看| 天天色 色综合| 精品国产乱子伦| 色哟哟精品一区| 中文字幕一区二区人妻| 欧美性xxxxxx少妇| 91久久国语露脸精品国产高跟| 欧美人妖巨大在线| 国产高清免费av| 亚洲成人激情在线| 人成在线免费视频| 中文字幕av一区中文字幕天堂| 免费网站成人| 欧美国产日韩一区二区| 激情视频网站在线播放色| 国产xxx69麻豆国语对白| 91av一区| 99国产盗摄| 日本福利一区| 午夜精品美女久久久久av福利| 我不卡手机影院| 国产曰肥老太婆无遮挡| 老司机一区二区三区| 欧美午夜aaaaaa免费视频| 精品一区二区综合| 秘密基地免费观看完整版中文| 91在线观看免费视频| 国产99在线 | 亚洲| 亚洲精品成人精品456| 日韩乱码人妻无码中文字幕| 欧美视频精品在线观看| www.色呦呦| 亚洲人成电影网站色| 成人区精品一区二区不卡| 97碰碰碰免费色视频| 成人自拍视频网| 国产高清一区视频| 欧美日韩中文一区二区| 国产欧美123| 日韩国产一区二| 久久黄色一级视频| 久久久精品黄色| 免费毛片在线播放免费| 色婷婷狠狠综合| 亚洲第一视频在线| 一本大道亚洲视频| bl视频在线免费观看| 国产精品在线看| 日韩免费电影在线观看| 99精品一级欧美片免费播放| 亚洲永久网站| 潘金莲一级淫片aaaaa| 国产日韩欧美激情| 国产精品第一页在线观看| 欧美日韩一区三区四区| 五月天婷婷在线观看| 久久亚洲精品成人| 欧美momandson| 国产精品对白刺激久久久| 日韩精品久久| 久久精品一区二| 99这里只有久久精品视频| 精品人妻伦九区久久aaa片| 色婷婷av一区| 午夜激情在线视频| 色综合久久悠悠| 天堂久久一区| 色噜噜一区二区| 性欧美精品高清| 亚洲中文字幕无码一区| 亚洲同性gay激情无套| 波多野结衣人妻| 亚洲精品自产拍| 擼擼色在线看观看免费| 国产chinese精品一区二区| 天天av综合| av中文字幕网址| 亚洲国产成人自拍| 亚洲av无码乱码国产精品fc2| 日韩精品在线免费| yellow在线观看网址| 国产精品久久亚洲| 欧美日韩国产探花| 色偷偷中文字幕| 亚洲欧美日韩精品久久久久| 一区二区日韩在线观看| 在线观看日韩欧美| 自拍偷拍欧美视频| 奇米视频888战线精品播放| 香蕉成人久久| 亚洲第一成人网站| 色一区在线观看| 第一页在线观看| 国产精品视频精品| 日韩欧美综合| 国产高清999| 亚洲另类春色国产| 国产成人久久精品77777综合 | 欧美不卡在线视频| 日本高清在线观看视频| 99在线首页视频| 亚洲香蕉网站| 国产精品无码电影| 欧美性猛交xxxx黑人| 蜜桃视频在线观看视频| 国产精品极品美女粉嫩高清在线| 欧美色就是色| 特级西西444www| 亚洲mv在线观看| 青春有你2免费观看完整版在线播放高清 | 欧美久久综合| 麻豆精品国产传媒av| 欧美午夜宅男影院在线观看| 超碰国产在线| 91香蕉嫩草影院入口| 国产精品成人一区二区网站软件| 亚洲色图欧美另类| 色综合天天综合色综合av | 西瓜成人精品人成网站| 日本三级免费观看| 国产精品久久三| 亚洲AV无码国产精品午夜字幕| 97人洗澡人人免费公开视频碰碰碰| 日韩av午夜| 久久这里只精品| 亚洲一区二区在线播放相泽| 日本a一级在线免费播放| 国产欧美亚洲精品| 亚洲午夜极品| 91在线无精精品白丝| 91精品国产色综合久久ai换脸 | 国产色综合天天综合网| 欧美日韩第一区| 亚洲天堂视频一区| 欧美日韩不卡一区| 9lporm自拍视频区在线| 亚洲国产欧美一区二区三区不卡| 国产成人午夜精品5599| 九九热在线免费观看| 日韩一区二区三区xxxx| 久久香蕉网站| 亚洲精品免费一区亚洲精品免费精品一区 | 成人性生活视频| 浴室偷拍美女洗澡456在线| 91啪亚洲精品| 精品国产99久久久久久宅男i| 亲子乱一区二区三区电影| 91精品二区| 一级片视频免费看|